안녕하세요

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


페이지 목록

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의 도움을 받아 작성하였습니다.

댓글 없음:

댓글 쓰기