Skip to content

4 ‐ BulletManager

문현우 edited this page Sep 13, 2023 · 10 revisions

📌 BulletManager

🎇 Managed by 김광수

  • Bullet을 관리하는 기능을 담당합니다.

📜 Code Summary

  • Awake()

    • 인스턴스 변수를 BulletManager 개체로 초기화합니다.
  • ShotBullet()

    • 지정된 유형과 속도로 탄환을 발사하는 메서드입니다.
    • Prefabs 배열에서 지정된 spawnPos위치와 지정된 Quaternion회전으로 게임오브젝트를 인스턴스화합니다.
    • 탄환의 속도를 지정된 속도로 설정합니다.

💻 Code

BulletManager.cs
using UnityEngine;

public enum BulletType
{
    Enemy,
    Player,
    Potion,
    Bomb,
}

public class BulletManager : MonoBehaviour
{
    public static BulletManager Instance { get; private set; }

    [SerializeField] private GameObject[] prefabs = new GameObject[4];

    public Camera mainCamera;

    private void Awake()
    {
        if (Instance == null) Instance = this;
    }

    public void ShotBullet(BulletType type, Vector3 spawnPos, float speed)
    {
        GameObject bullet = Instantiate(prefabs[(int)type], spawnPos, Quaternion.identity);
        bullet.GetComponent<Bullet>().speed = speed;
    }
}

✔️ Bullet

🎇 Managed by 김광수

  • Bullet 클래스는 ICharacter 인터페이스를 구현합니다.

📜 Code Summary

  • Start()

    • Bullet의 이동 방향을 Player의 위치로 설정하는 메서드입니다.
  • FixedUpdate()

    • Bullet의 물리적 업데이트를 처리합니다. Bullet의 이동 시킵니다.
  • Update()

    • Bullet이 화면 밖으로 나갈 경우 Bullet을 제거합니다.
  • RotateBullet(Vector3 pos)

    • Bullet의 이동 방향을 pos로 설정합니다.
  • MoveBullet()

    • Bullet을 moveDirection 방향으로 Speed만큼 이동시킵니다.
  • CheckOutScreen()

    • Bullet이 화면 밖으로 나갔는지 여부를 확인합니다. 만약 화면 밖으로 나갔다면, Bullet을 제거합니다.
  • AttackCharacter()

    • Bullet이 캐릭터를 공격합니다. 이 메서드에서는 Bullet을 제거합니다.
  • TakeDamage()

    • Bullet을 제거합니다.

💻 Code

Bullet.cs
using UnityEngine;

public class Bullet : MonoBehaviour,ICharacter
{
    [SerializeField] protected Rigidbody2D rb2D;
    protected Vector3 moveDirection = Vector3.zero;
    public float speed;

    protected virtual void Start()
    {
        RotateBullet(PlayerManager.Instance.player.transform.position);
    }
    protected void FixedUpdate()
    {
        MoveBullet();
    }

    protected void Update()
    {
        CheckOutScreen();
    }
    protected void RotateBullet(Vector3 pos)
    {
        moveDirection = (pos - transform.position).normalized;

        float rotZ = Mathf.Atan2(moveDirection.y, moveDirection.x) * Mathf.Rad2Deg + Random.Range(-80f, 80f);
        moveDirection = Quaternion.AngleAxis(rotZ, Vector3.up) * moveDirection;

        transform.rotation = Quaternion.Euler(0, 0, rotZ);
    }

    protected void MoveBullet()
    {
        rb2D.velocity = moveDirection * speed ;
    }
    protected void CheckOutScreen()
    {
        Vector3 screenPos = BulletManager.Instance.mainCamera.WorldToViewportPoint(transform.position);

        if (screenPos.x > 1 || screenPos.x < 0 || screenPos.y > 1 || screenPos.y < 0)
        {
            Destroy(gameObject);
        }
    }
    public virtual void AttackCharacter()
    {
        Destroy(gameObject);
    }
    public virtual void TakeDamage()
    {
        Destroy(gameObject);
    }

    
}

✔️ Bomb

🎇 Managed by 김광수

  • Bomb, 폭탄을 관리하는 기능을 담당합니다. Bullet 클래스를 상속하고 있습니다.

📜 Code Summary

  • OnTriggerEnter2D()

    • 폭탄이 다른 Collider2D 객체와 충돌할 때 호출됩니다.
    • 폭탄이 아직 맞지 않았다면, 충돌하는 객체가 Player인지 확인합니다.
    • 만약 player라면, Player가 공격중(왼쪽 마우스)인지 확인합니다.
    • Player가 공격 중이라면, HitBomb()메서드를 호출합니다.
    • 공격 중이지 않으면, BurstBomb() 메서드를 호출합니다.
  • HitBomb()

    • isHit 플래그를 ture로 설정하고, 폭탄의 속도를 증가시키며, 폭탄의 방향을 무작위로 회전시킵니다.
  • BurstBomb()

    • AttackCharacter() 메서드를 호출하여 폭탄의 폭발 범위 내에 있는 캐릭터를 공격합니다.
    • 폭탄의 현재 위치에 폭발 애니메이션을 배치합니다.

💻 Code

Bomb.cs
using UnityEngine;

public class Bomb : Bullet
{
    [SerializeField] private GameObject burstPrefabs;
    bool isHit = false;
    public void OnTriggerEnter2D(Collider2D collision)
    {
        if (!isHit)
        {
            Player player = collision.GetComponentInParent<Player>();
            if (player != null)
            {
                if (player.IsAttack)
                {
                    HitBomb();
                }
                else
                {
                    BurstBomb();
                }
            }
        }
        else
        {
            Enemy enemy = collision.GetComponentInParent<Enemy>();
            if (enemy != null)
            {
                BurstBomb();
            }
        }
        
    }

    public void BurstBomb()
    {
        AttackCharacter();
        Instantiate(burstPrefabs,transform.position, Quaternion.identity);
        
    }

    public void HitBomb()
    {
        isHit = true;
        float rotZ = Random.Range(-20f, 20f);
        moveDirection = Quaternion.AngleAxis(rotZ, Vector3.up) * moveDirection * -1;
        speed += 1f;
    }
}

✔️ EnemyBullet

🎇 Managed by 김광수

  • Bullet 클래스를 상속합니다.

📜 Code Summary

  • OnTriggerEnter2D()
    • EnemyBullet이 다른 Collider2D 객체와 충돌할 때 호출됩니다.
    • 충돌하는 객체가 Player인지 확인합니다.
    • 만약 Player라면, AttackCharacter() 메서드를 호출하여 Player를 공격하고,
    • Player.TakeDamage() 메서드를 호출하여 Player에게 데미지를 입힙니다

💻 Code

EnemyBullet.cs
using UnityEngine;

public class EnemyBullet : Bullet
{ 
    public void OnTriggerEnter2D(Collider2D collision)
    {
        Player player = collision.GetComponentInParent<Player>();
        if (player != null)
        {
            AttackCharacter();
            player.TakeDamage();
        }
    }
}

✔️ Potion

🎇 Managed by 김광수

  • Bullet 클래스를 상속합니다.
  • Potion은 플레이어에게 체력을 회복시켜주는 아이템입니다. 플레이어가 Potion을 획득하면, TakePotion() 메서드가 호출되어 플레이어의 체력이 회복됩니다.

📜 Code Summary

  • OnTriggerEnter2D()
    • EnemyBullet이 다른 Collider2D 객체와 충돌할 때 호출됩니다.
    • 충돌하는 객체가 Player인지 확인합니다.
    • 만약 Player라면, AttackCharacter() 메서드를 호출하여 Player를 공격하고,
    • Player.TakePotion() 메서드를 호출하여 Player에게 포션을 사용합니다.

💻 Code

Potion.cs
using UnityEngine;

public class Potion : Bullet
{
    public void OnTriggerEnter2D(Collider2D collision)
    {
        Player player = collision.GetComponentInParent<Player>();
        if (player != null)
        {
            AttackCharacter();
            player.TakePotion();
        }
    }

}

✔️ Burst

🎇 Managed by 김광수

  • 폭발 효과를 구현하는 기능을 담당합니다.

📜 Code Summary

  • Update()

    • time 필드의 값을 Time.deltaTime만큼 감소시킵니다.
    • 만약 time 필드의 값이 0보다 작으면, Burst 오브젝트를 제거합니다.
  • OnTriggerEnter2D()

    • collision.GetComponentInParent() 함수를 사용하여 충돌한 오브젝트의 Bullet, Player, Enemy 중 하나의 인스턴스를 가져옵니다.
    • 만약 해당 오브젝트가 존재하면, 해당 오브젝트의 TakeDamage() 메서드를 호출하여 데미지를 입힙니다.

💻 Code

Burst.cs
using UnityEngine;

public class Burst : MonoBehaviour
{
    float time = 1f;    
    private void Update()
    {
        time -= Time.deltaTime;
        if (time < 0)
        {
            Destroy(gameObject);
        }
    }
    private void OnTriggerEnter2D(Collider2D collision)
    {
        Bullet bullet = collision.GetComponentInParent<Bullet>();
        Player player = collision.GetComponentInParent<Player>();
        Enemy enemy = collision.GetComponentInParent<Enemy>();
        if (bullet != null)
        {
            bullet.TakeDamage();
        }
        else if (player != null)
        {
            player.TakeDamage();
        }
        else if(enemy != null)
        {
            enemy.TakeDamage();
        }
    }
  
}

Clone this wiki locally