안녕하세요

프로그램 과정에서 막혔던 문제들에 대한 해결책 정리


페이지 목록

레이블이 보스가 날린 파이어볼을 플레이어에게 날리기인 게시물을 표시합니다. 모든 게시물 표시
레이블이 보스가 날린 파이어볼을 플레이어에게 날리기인 게시물을 표시합니다. 모든 게시물 표시

2025년 11월 22일 토요일

[유니티][Unity][MVC] 보스가 날린 파이어볼을 플레이어에게 날리기

  보스가 날리는 파이어볼이 플레이어에게 날아가고 플레이어에 닿으면 없어지면서 데미지를 넣어 보자.


FireballModel.cs

using UnityEngine;


public class FireballModel

{

    public float Speed { get; private set; }

    public float Damage { get; private set; }

    public float Lifetime { get; private set; }


    public FireballModel(float speed, float damage, float lifeTime)

    {

        Speed = speed;

        Damage = damage;

        Lifetime = lifeTime;

    }

}


Fireview.cs
using UnityEngine;
using System;

public class FireballView : MonoBehaviour
{
    // Start is called once before the first execution of Update after the MonoBehaviour is created
    private Rigidbody2D rb;
    public event Action<Collider2D, FireballView> OnHit;


    void Start()
    {
        
    }

    private void Awake()
    {
        rb = GetComponent<Rigidbody2D>();
        if( rb == null)
        {
            Debug.LogError("FireballView requires a Rigidbody component!");
        }
    }

    public void Launch(Vector2 direction, float speed)
    {
        if(rb != null)
        {
            rb.linearVelocity = direction * speed;
            //rb.useGravity = false;
        }

    }
   

    void OnTriggerEnter2D(Collider2D other)
    {
        Debug.Log("fireballview oncollisionenter");
        OnHit?.Invoke(other, this);
      
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}

BossController.cs
using System.Collections;
using UnityEngine;
using UnityEngine.UIElements;
using static UnityEngine.GraphicsBuffer;

public GameObject fireballPrefab;
//public Transform firePoint;
public float shootInterval = 2f;
public float fireballSpeed = 4f;
public float fireballDamage = 10f;
public float fireballLifeTime = 5f;


void Start()
{
    StartSkill();
}

public void StartSkill()
{
    //if (isCooldown) return;
    //isCooldown = true;

    // 주인공 위치 기준으로 스킬 시작
    if (player == null)
    {
        Debug.Log("player is null");
    }
    Vector2 targetPosition = player.position;
    

    // 일정 시간 후 스킬 발동
    StartCoroutine(ActivateSkillAfterDelay(targetPosition, bossSkillModel.WarningDuration));
    //Invoke(nameof(() => ActivateSkill(targetPosition)), bossSkillModel.WarningDuration);
    //Invoke(nameof(ResetCooldown), cooldownDuration);
}

IEnumerator ActivateSkillAfterDelay(Vector2 targetPosition, float delay)
{
    while (true)
    {
        yield return new WaitForSeconds(delay);
        if(Random.value > 0.5f)
        {
            Vector2 playerPosition = player.position;
            bossSkillView.ShowWarning(playerPosition, bossSkillModel.Radius);

            yield return new WaitForSeconds(skillWaitTime);

            ActivateSkill(targetPosition);
        }
        else
        {
            Shoot();
        }
        
    }
}

 void Shoot()
 {
     FireballModel model = new FireballModel(fireballSpeed, fireballDamage, fireballLifeTime);
     //Debug.Log("fire Point : " + firePoint.position);
     Vector2 firePosition = new Vector3(0.5f,3.5f);
     GameObject fireballGO = Instantiate(fireballPrefab, firePosition, Quaternion.identity);
     fireballGO.SetActive(true);
     FireballView view = fireballGO.GetComponent<FireballView>();

     if( view != null)
     {
         view.OnHit += (collider2D, fireballView) => OnFireballHit(collider2D, model, view);

         if (player == null)
         {
             Debug.Log("player is null");
         }
         Vector2 playerPosition = player.position;
         Vector2 shootDirection = (playerPosition - firePosition).normalized;
         Debug.Log("Shoot Direction: " + shootDirection);
         view.Launch(shootDirection, model.Speed);

         Destroy(fireballGO, model.Lifetime);
     }
 }

 void OnFireballHit(Collider2D other , FireballModel model, FireballView fireballView)
 {
     Debug.Log("player attack fireball");
     if (other.gameObject.CompareTag("Player"))
     {
         int minAttackPower = Mathf.RoundToInt(bossSkillModel.Damage - 20);
         int maxAttackPower = Mathf.RoundToInt(bossSkillModel.Damage);
         Debug.Log("player attack 2");
         other.gameObject.GetComponent<MainCharController>()?.TakeDamage(minAttackPower, maxAttackPower);

         if (fireballView != null)
         {
             Debug.Log("destroy fireball");
             Destroy(fireballView.gameObject);
         }
     }

     
     //Destroy(other.gameObject);
 }

본문은 구글 AI의 도움을 받아 작성하였습니다.