오브젝트 풀링

2025. 5. 16. 09:47개발일지/Journey to West

Destroy 후의 Garbage Correct 에 의한 성능 저하를 예방하기 위해 ObjectPooling 으로 전환을 합니다.

ObjectManager Scripts

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ObjectManager : MonoBehaviour
{
    [Header("Enemy")]
    public GameObject enemyAcornPrefab;
    public GameObject enemyCatPrefab;
    public GameObject enemyDollPrefab;

    [Header("Item")]
    public GameObject itemCoinPrefab;
    public GameObject itemPowerPrefab;
    public GameObject itemBoomPrefab;

    [Header("Player Bullet")]
    public GameObject bulletPlayerAPrefab;
    public GameObject bulletPlayerBPrefab;
    public GameObject bulletPlayerCPrefab;
    public GameObject bulletPlayerLPrefab;
    public GameObject bulletPlayerRPrefab;
    public GameObject energyBulletPrefab;

    [Header("Enemy Bullet")]
    public GameObject enemyBulletAPrefab;
    public GameObject enemyBulletBPrefab;

    // Enemy
    GameObject[] enemyAcorn;
    GameObject[] enemyCat;
    GameObject[] enemyDoll;

    // Item
    GameObject[] itemCoin;
    GameObject[] itemPower;
    GameObject[] itemBoom;

    // Player Bullet
    GameObject[] bulletPlayerA;
    GameObject[] bulletPlayerB;
    GameObject[] bulletPlayerC;
    GameObject[] bulletPlayerL;
    GameObject[] bulletPlayerR;
    GameObject[] energyBullet;

    // Enemy Bullet
    GameObject[] enemyBulletA;
    GameObject[] enemyBulletB;

    GameObject[] targetPool;

    void Awake()
    {
        enemyDoll = new GameObject[20];
        enemyCat = new GameObject[20];
        enemyAcorn = new GameObject[20];

        itemCoin = new GameObject[20];
        itemPower = new GameObject[10];
        itemBoom = new GameObject[10];

        bulletPlayerA = new GameObject[100];
        bulletPlayerB = new GameObject[100];
        bulletPlayerC = new GameObject[100];
        bulletPlayerL = new GameObject[100];
        bulletPlayerR = new GameObject[100];
        energyBullet = new GameObject[100];

        enemyBulletA = new GameObject[100];
        enemyBulletB = new GameObject[100];

        Generate();
    }

    void Generate()
    {   // Enemy
        for(int index = 0; index < enemyAcorn.Length; index++)
        {
            enemyAcorn[index] = Instantiate(enemyAcornPrefab);
            enemyAcorn[index].SetActive(false);
        }
        for(int index = 0; index < enemyCat.Length; index++)
        {
            enemyCat[index] = Instantiate(enemyCatPrefab);
            enemyCat[index].SetActive(false);
        }
        for (int index = 0; index < enemyDoll.Length; index++)
        {
            enemyDoll[index] = Instantiate(enemyDollPrefab);
            enemyDoll[index].SetActive(false);
        }

        // Item
        for (int index = 0; index < itemCoin.Length; index++)
        {
            itemCoin[index] = Instantiate(itemCoinPrefab);
            itemCoin[index].SetActive(false);
        }
        for (int index = 0; index < itemPower.Length; index++)
        {
            itemPower[index] = Instantiate(itemPowerPrefab);
            itemPower[index].SetActive(false);
        }
        for (int index = 0; index < itemBoom.Length; index++)
        {
            itemBoom[index] = Instantiate(itemBoomPrefab);
            itemBoom[index].SetActive(false);
        }

        // Player Bullet
        for (int index = 0; index < bulletPlayerA.Length; index++)
        {
            bulletPlayerA[index] = Instantiate(bulletPlayerAPrefab);
            bulletPlayerA[index].SetActive(false);
        }
        for (int index = 0; index < bulletPlayerB.Length; index++)
        {
            bulletPlayerB[index] = Instantiate(bulletPlayerBPrefab);
            bulletPlayerB[index].SetActive(false);
        }
        for (int index = 0; index < bulletPlayerC.Length; index++)
        {
            bulletPlayerC[index] = Instantiate(bulletPlayerCPrefab);
            bulletPlayerC[index].SetActive(false);
        }
        for (int index = 0; index < bulletPlayerL.Length; index++)
        {
            bulletPlayerL[index] = Instantiate(bulletPlayerLPrefab);
            bulletPlayerL[index].SetActive(false);
        }
        for (int index = 0; index < bulletPlayerR.Length; index++)
        {
            bulletPlayerR[index] = Instantiate(bulletPlayerRPrefab);
            bulletPlayerR[index].SetActive(false);
        }
        for (int index = 0; index < energyBullet.Length; index++)
        {
            energyBullet[index] = Instantiate(energyBulletPrefab);
            energyBullet[index].SetActive(false);
        }

        // Enemy Bullet
        for (int index = 0; index < enemyBulletA.Length; index++)
        {
            enemyBulletA[index] = Instantiate(enemyBulletAPrefab);
            enemyBulletA[index].SetActive(false);
        }
        for (int index = 0; index < enemyBulletB.Length; index++)
        {
            enemyBulletB[index] = Instantiate(enemyBulletBPrefab);
            enemyBulletB[index].SetActive(false);
        }
    }
    public GameObject MakeObj(string type)
    {
        switch (type)
        {
            case "enemyAcorn":
                targetPool = enemyAcorn;
                break;
            
            case "enemyCat":
                targetPool = enemyCat;
                break;
            
            case "enemyDoll":
                targetPool = enemyDoll;
                break;

            case "itemCoin":
                targetPool = itemCoin;
                break;

            case "itemPower":
                targetPool = itemPower;
                break;

            case "itemBoom":
                targetPool = itemBoom;
                break;

            case "bulletPlayerA":
                targetPool = bulletPlayerA;
                break;

            case "bulletPlayerB":
                targetPool = bulletPlayerB;
                break;

            case "bulletPlayerC":
                targetPool = bulletPlayerC;
                break;

            case "bulletPlayerL":
                targetPool = bulletPlayerL;
                break;

            case "bulletPlayerR":
                targetPool = bulletPlayerR;
                break;

            case "energyBullet":
                targetPool = energyBullet;
                break;

            case "enemyBulletA":
                targetPool = enemyBulletA;
                break;

            case "enemyBulletB":
                targetPool = enemyBulletB;
                break;
        }

        for (int index = 0; index < targetPool.Length; index++)
        {
            if (!targetPool[index].activeSelf)
            {
                targetPool[index].SetActive(true);
                return targetPool[index];
            }
        }
        return null;
    }

    public GameObject[]GetPool(string type)
    {
        switch (type)
        {
            case "enemyAcorn":
                targetPool = enemyAcorn;
                break;

            case "enemyCat":
                targetPool = enemyCat;
                break;

            case "enemyDoll":
                targetPool = enemyDoll;
                break;

            case "itemCoin":
                targetPool = itemCoin;
                break;

            case "itemPower":
                targetPool = itemPower;
                break;

            case "itemBoom":
                targetPool = itemBoom;
                break;

            case "bulletPlayerA":
                targetPool = bulletPlayerA;
                break;

            case "bulletPlayerB":
                targetPool = bulletPlayerB;
                break;

            case "bulletPlayerC":
                targetPool = bulletPlayerC;
                break;

            case "bulletPlayerL":
                targetPool = bulletPlayerL;
                break;

            case "bulletPlayerR":
                targetPool = bulletPlayerR;
                break;

            case "energyBullet":
                targetPool = energyBullet;
                break;

            case "enemyBulletA":
                targetPool = enemyBulletA;
                break;

            case "enemyBulletB":
                targetPool = enemyBulletB;
                break;
        }

        return targetPool;
    }

}

Object Pooling 으로 인한 코드 변경이 필수

GameManager Scripts - enemy 를 관리하기 위해 변경해야함.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;

public class GameManager : MonoBehaviour
{
    public string[] enemyObjects;
    public Transform[] spawnPoints;

    public float maxSpawnDelay;
    public float curSpawnDelay;

    public GameObject player;

    public Text scoreText;
    public Image[] lifeImage;
    public GameObject gameOverset;

    public ObjectManager objectManager; // 추가

    private void Awake()
    {
        enemyObjects = new string[] { "enemyAcorn", "enemyCat", "enemyDoll" };
    }

    private void Update()
    {
        curSpawnDelay += Time.deltaTime;

        if(curSpawnDelay > maxSpawnDelay)
        {
            SpawnEnemy();
            maxSpawnDelay = Random.Range(0.5f, 3f);
            curSpawnDelay = 0;
        }
        // # UI Score Update
        Player playerLogic = player.GetComponent<Player>();
        scoreText.text = string.Format("{0:n0}", playerLogic.score);

    }

    void SpawnEnemy()
    {
        int ranEnemy = Random.Range(0, 3);
        int ranPoint = Random.Range(0, 9);
        GameObject enemy = objectManager.MakeObj(enemyObjects[ranEnemy]); // 변경
        enemy.transform.position = spawnPoints[ranPoint].position;

        Rigidbody2D rigid = enemy.GetComponent<Rigidbody2D>();
        Enemy enemyLogic = enemy.GetComponent<Enemy>();
        enemyLogic.player = player;
        enemyLogic.objectManager = objectManager; // 추가됨

        if (ranPoint == 5 || ranPoint == 6) //Right spawn
        {
            rigid.velocity = new Vector2(enemyLogic.speed * (-1), -1);
        }
        else if (ranPoint == 7 || ranPoint == 8) // LeftSpawn
        {
            rigid.velocity = new Vector2(enemyLogic.speed, -1);
        }
        else
        {
            rigid.velocity = new Vector2(0,enemyLogic.speed *(-1));
        }
    }
    public void UpdateLifeIcon(int life)
    {
        Debug.Log("UpdateLifeIcon 실행됨: " + life);

        // # UI Life Init Disable
        for (int index = 0; index < 3; index++)
        {
            lifeImage[index].color = new Color(1, 1, 1, 0);

        }
        // # UI Life Init Active
        for (int index = 0; index < life; index++)
        {
            lifeImage[index].color = new Color(1, 1, 1, 1);

        }
    }

    public void RespawnPlayer()
    {
        Invoke("RespawnPlayerExe", 2f);
    }

    void RespawnPlayerExe()
    {
        player.transform.position = (Vector3.down * 4f) + (Vector3.right * 0.4f);
        player.SetActive(true);

        Player playerLogic = player.GetComponent<Player>();
        playerLogic.isHit = false;
    }

    public void GameOver()
    {
        gameOverset.SetActive(true);
    }

    public void GameRetry()
    {
        SceneManager.LoadScene(0);
    }
}

 

Enemy Scripts - enemyBullet을 풀링하기 때문에 바꿔야함.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.U2D;

public class Enemy : MonoBehaviour
{
    public string enemyName;
    public int enemyScore;

    public float speed;
    public int health;
    private int defaultHealth; // 적의 초기 체력 저장 변수


    Animator anim;
    Rigidbody2D rigid;

    public float maxShotDelay;
    public float curShotDealy;

    public GameObject bulletEnemyA;
    public GameObject bulletEnemyB;
    public GameObject itemCoin;
    public GameObject itemPower;
    public GameObject itemBoom;

    public GameObject player;
    public ObjectManager objectManager; //추가

    private void Awake()
    {
        anim = GetComponent<Animator>();
        defaultHealth = health; // 프리팹에 설정된 초기값 저장

    }

    private void Update()
    {
        Shoot();
        Reload();
    }

    public void Shoot()
    {
        if (curShotDealy < maxShotDelay) 
        {
            return;
        }

        if (enemyName == "Acorn")
        {
            GameObject bullet = objectManager.MakeObj("enemyBulletA"); //오브젝트 풀링으로 가져옴
            bullet.transform.position = transform.position;

            Rigidbody2D rigid = bullet.GetComponent<Rigidbody2D>();
            Vector3 dirVec = player.transform.position - transform.position;
            
            rigid.AddForce(dirVec.normalized * 3, ForceMode2D.Impulse);
        }
        else if (enemyName == "Cat")
        {
            GameObject bullet = objectManager.MakeObj("enemyBulletB"); //오브젝트 풀링으로 가져옴
            bullet.transform.position = transform.position;

            Rigidbody2D rigid = bullet.GetComponent<Rigidbody2D>();
            Vector3 dirVec = player.transform.position - transform.position;

            rigid.AddForce(dirVec.normalized * 3, ForceMode2D.Impulse);
        }
        else if (enemyName == "Doll")
        {
            GameObject bulletR = objectManager.MakeObj("enemyBulletA"); //오브젝트 풀링으로 가져옴
            bulletR.transform.position = transform.position + Vector3.right * 0.3f;
            
            GameObject bulletL = objectManager.MakeObj("enemyBulletA"); //오브젝트 풀링으로 가져옴
            bulletL.transform.position = transform.position + Vector3.left * 0.3f;

            Rigidbody2D rigidR = bulletR.GetComponent<Rigidbody2D>();
            Rigidbody2D rigidL = bulletL.GetComponent<Rigidbody2D>();

            Vector3 dirVecR = player.transform.position - (transform.position + Vector3.right * 0.3f);
            Vector3 dirVecL = player.transform.position - (transform.position + Vector3.left * 0.3f);

            rigidR.AddForce(dirVecR.normalized * 3, ForceMode2D.Impulse);
            rigidL.AddForce(dirVecL.normalized * 3, ForceMode2D.Impulse);
        }
        curShotDealy = 0;    
    }
    void Reload()
    {
        curShotDealy += Time.deltaTime;
    }

    private void OnEnable() //오브젝트 풀링으로 인한 체력초기화 문제로인해 추가해야함.
    {
        // 적이 새롭게 등장할 때 기본 체력으로 초기화
        health = defaultHealth; // 풀링된 적이 다시 등장할 때 초기 값 유지
    }


    public void OnHit(int dmg)
    {
        if (health <= 0) return;

        health -= dmg;
        health = Mathf.Max(health, 0); // 체력이 음수가 되는 것 방지

        anim.SetTrigger("dead");

        if (health <= 0)
        {
            gameObject.SetActive(false);
        }

        if (health <= 0)
        {
            Player playerLogic = player.GetComponent<Player>();
            playerLogic.score += enemyScore;

            // 아이템 떨구기 Random Ratio item drop
            int ran = Random.Range(0, 10);
            if(ran < 3)
            {
                Debug.Log("Not Item");
            }
            else if( ran < 6) // Coin
            {
                Instantiate(itemCoin, transform.position, itemCoin.transform.rotation);
            }
            else if (ran < 8) // power
            {
                Instantiate(itemPower, transform.position, itemPower.transform.rotation);
            }
            else if (ran < 10) // Boom
            {
                Instantiate(itemBoom, transform.position, itemBoom.transform.rotation);
            }

            gameObject.SetActive(false);
            //transform.rotation = Quaternion.identity;
        }
    }

    private void OnTriggerEnter2D(Collider2D collision)
    {

        if(collision.gameObject.tag == "BorderBullet")
        {
            gameObject.SetActive(false); // Destroy 에서 SetActive 로 변경
            //transform.rotation = Quaternion.identity;
        }
        else if (collision.gameObject.CompareTag("PlayerBullet"))
        {
            Bullet bullet = collision.gameObject.GetComponent<Bullet>();
            EnergyBullet energyBullet = collision.gameObject.GetComponent<EnergyBullet>();

            int damage = bullet != null ? bullet.dmg : (energyBullet != null ? energyBullet.dmg : 0);

            OnHit(damage);

        }
    }
}

Player Scripts - bullet, energyBullet 등의 object Pooling 으로 인한 변경

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;

public class Player : MonoBehaviour
{

    [SerializeField]
    private float speed;
    public int power;
    public int maxPower;
    public int boom;
    public int maxBoom;

    private Vector2 moveInput;
    private Rigidbody2D rigid;
    public float fireRate;
    public float nextFireTime;

    public float curChargeTime;
    public float chargeTime;
    private Animator anim;
    public Transform bulletSpawnPoint;

    public GameObject bulletObjA;
    public GameObject bulletObjB;
    public GameObject bulletObjC;
    public GameObject smallBullet1;
    public GameObject smallBullet2;
    public GameObject energyBullet;
    public GameObject boomEffect;

    private bool isFiring = false;
    private bool isChargeAttack = false;
    public bool isHit;
    public GameManager gameManager;
    public ObjectManager objectManager; // 추가
    //private bool isDead = false;

    public int score;
    public int life;


    private void Awake()
    {
        rigid = GetComponent<Rigidbody2D>();
        anim = GetComponent<Animator>();
    }

    public void OnBoom(InputAction.CallbackContext context)
    {
        if (context.started && boom > 0)
        {
            boom--;
            boomEffect.SetActive(true);
            StartCoroutine(BoomEffectRoutine()); // 4초간 지속적으로 제거
        }
    }

    private IEnumerator BoomEffectRoutine()
    {
        float duration = 4f; // 지속 시간
        float elapsedTime = 0f;

        while (elapsedTime < duration)
        {
            // # 여러 종류의 적을 반복문으로 가져와 리스트에 저장
            string[] enemyTypes = { "enemyAcorn", "enemyCat", "enemyDoll" };
            List<GameObject> enemies = new List<GameObject>();

            foreach (string enemyType in enemyTypes)
            {
                GameObject[] enemyPool = objectManager.GetPool(enemyType);
                if (enemyPool != null) // 풀이 존재할 경우에만 추가
                {
                    foreach (GameObject enemy in enemyPool)
                    {
                        if (enemy.activeSelf) // 활성화된 적만 추가
                        {
                            enemies.Add(enemy);
                        }
                    }
                }
            }

            // # 모든 적에게 지속적으로 데미지 주기
            foreach (GameObject enemy in enemies)
            {
                Enemy enemyLogic = enemy.GetComponent<Enemy>();
                enemyLogic?.OnHit(500); // 널 체크 후 데미지 적용
            }

            // # 적의 총알도 제거 (자동 반복문 적용)
            string[] bulletTypes = { "enemyBulletA", "enemyBulletB" };

            foreach (string bulletType in bulletTypes)
            {
                GameObject[] enemyBullets = objectManager.GetPool(bulletType);
                if (enemyBullets != null) // 널 체크 추가
                {
                    foreach (GameObject bullet in enemyBullets)
                    {
                        bullet.SetActive(false); //Destory 에서 변경
                    }
                }
            }

            elapsedTime += 0.5f;
            yield return new WaitForSeconds(0.5f);
        }

        boomEffect.SetActive(false); // 4초 후 효과 종료 , Boomd 을 계속활용하는 것, ObjectPooling과 상관없음.
    }



    private Coroutine chargeCoroutine;
    // 차지어택
    public void OnChargeAttack(InputAction.CallbackContext context)
    {
        if (context.started && chargeCoroutine == null)
        {
            isChargeAttack = true;
            curChargeTime = 0;
            chargeCoroutine = StartCoroutine(ChargeEnergy());
        }
        else if (context.canceled)
        {
            isChargeAttack = false;
            curChargeTime = 0;

            if (chargeCoroutine != null)
            {
                StopCoroutine(chargeCoroutine);
                chargeCoroutine = null; // 코루틴 참조 초기화

            }
        }
    }

    private IEnumerator ChargeEnergy()
    {
        while (curChargeTime < chargeTime)
        {
            anim.SetTrigger("cha_bigshot"); // 애니메이션 
            yield return new WaitForSeconds(1f); // 애니메이션이 1초짜리임.
            curChargeTime++;
        }

        if (isChargeAttack) // 차지가 끝났을 때만 공격 허용
        {
            chargeShoot(); // 발사!
            curChargeTime = 0; //
        }
    }

    public void chargeShoot()
    {
        GameObject chargeShot = Instantiate(energyBullet, bulletSpawnPoint.position, transform.rotation);
        GameObject chargeShot1 = Instantiate(energyBullet, bulletSpawnPoint.position, transform.rotation);
        if (chargeShot && chargeShot1 != null){
            Rigidbody2D rigid = chargeShot.GetComponent<Rigidbody2D>();
            Rigidbody2D rigid1 = chargeShot1.GetComponent<Rigidbody2D>();
            rigid.AddForce(Vector2.up * 10, ForceMode2D.Impulse);
            rigid.angularVelocity = 360f; // 초당 360도 회전
            rigid1.AddForce(Vector2.up * 10, ForceMode2D.Impulse);
            rigid1.angularVelocity = -360f; // 초당 360도 회전
        }
    }

    // # 일반공격
    public void OnFire(InputAction.CallbackContext context)
    {
        if (context.started)
        {
            isFiring = true;
            StartCoroutine(FireContinuously());
        }

        else if (context.canceled)
        {
            isFiring = false;
        }
    }
    //일반공격에 대한 Couroutine
    private IEnumerator FireContinuously()
    {
        while (isFiring)
        {
            nextFireTime = Time.time + fireRate;
            Shoot();
            anim.SetTrigger("cha_shot");
            yield return new WaitForSeconds(fireRate);
        }
    }
    public void OnMove(InputAction.CallbackContext context)
    {
        moveInput = context.ReadValue<Vector2>();
    }
    private void FixedUpdate()
    {
        Vector2 newVec = moveInput.normalized * speed * Time.fixedDeltaTime;
        rigid.MovePosition(rigid.position + newVec);
    }

    // 일반공격 //
    public void Shoot()
    {
        switch (power)
        {
            case 1:
                GameObject bullet = objectManager.MakeObj("bulletPlayerA"); // bullet을 ObjectPooling
                bullet.transform.position = bulletSpawnPoint.position;

                bullet.GetComponent<Rigidbody2D>().AddForce(Vector2.up * 10, ForceMode2D.Impulse);
                /*GameObject bullet = Instantiate(bulletObjA, transform.position, transform.rotation);
                Rigidbody2D rigid = bullet.GetComponent<Rigidbody2D>();
                rigid.AddForce(Vector2.up * 10, ForceMode2D.Impulse);*/
                break;
            case 2:
                GameObject bullet1 = objectManager.MakeObj("bulletPlayerB");
                bullet1.transform.position = bulletSpawnPoint.position;

                Rigidbody2D rigid1 = bullet1.GetComponent<Rigidbody2D>();
                rigid1.AddForce(Vector2.up * 10, ForceMode2D.Impulse);
                break;
            case 3:
                GameObject bulletR = objectManager.MakeObj("bulletPlayerR");
                bulletR.transform.position = bulletSpawnPoint.position + Vector3.right * 0.2f;
                Rigidbody2D rigidR = bulletR.GetComponent<Rigidbody2D>();

                GameObject bulletC = objectManager.MakeObj("bulletPlayerA");
                bulletC.transform.position = bulletSpawnPoint.position;
                Rigidbody2D rigidC = bulletC.GetComponent<Rigidbody2D>();

                GameObject bulletL = objectManager.MakeObj("bulletPlayerL");
                bulletL.transform.position = bulletSpawnPoint.position + Vector3.left * 0.2f;
                Rigidbody2D rigidL = bulletL.GetComponent<Rigidbody2D>();

                float angle = 5f * Mathf.Deg2Rad;
                rigidR.AddForce(transform.up * 10 + transform.right * Mathf.Tan(angle) * 10, ForceMode2D.Impulse);
                rigidC.AddForce(Vector2.up * 10, ForceMode2D.Impulse);
                rigidL.AddForce(transform.up * 10 + transform.right * Mathf.Tan(-angle) * 10, ForceMode2D.Impulse);
                break;
            case 4:
                GameObject bulletR1 = objectManager.MakeObj("bulletPlayerR");
                bulletR1.transform.position = bulletSpawnPoint.position + Vector3.right * 0.3f;
                Rigidbody2D rigidR1 = bulletR1.GetComponent<Rigidbody2D>();

                GameObject bulletC1 = objectManager.MakeObj("bulletPlayerB");
                bulletC1.transform.position = bulletSpawnPoint.position;
                Rigidbody2D rigidC1 = bulletC1.GetComponent<Rigidbody2D>();

                GameObject bulletL1 = objectManager.MakeObj("bulletPlayerL");
                bulletL1.transform.position = bulletSpawnPoint.position + Vector3.left * 0.2f;
                Rigidbody2D rigidL1 = bulletL1.GetComponent<Rigidbody2D>();

                float angle1 = 5f * Mathf.Deg2Rad;
                rigidR1.AddForce(transform.up * 10 + transform.right * Mathf.Tan(angle1) * 10, ForceMode2D.Impulse);
                rigidC1.AddForce(Vector2.up * 10, ForceMode2D.Impulse);
                rigidL1.AddForce(transform.up * 10 + transform.right * Mathf.Tan(-angle1) * 10, ForceMode2D.Impulse);
                break;
            case 5:
                GameObject bulletR2 = objectManager.MakeObj("bulletPlayerR");
                bulletR2.transform.position = bulletSpawnPoint.position + Vector3.right * 0.3f;
                Rigidbody2D rigidR2 = bulletR2.GetComponent<Rigidbody2D>();

                GameObject bulletC2 = objectManager.MakeObj("bulletPlayerC");
                bulletC2.transform.position = bulletSpawnPoint.position;
                Rigidbody2D rigidC2 = bulletC2.GetComponent<Rigidbody2D>();

                GameObject bulletL2 = objectManager.MakeObj("bulletPlayerL");
                bulletL2.transform.position = bulletSpawnPoint.position + Vector3.left * 0.2f;
                Rigidbody2D rigidL2 = bulletL2.GetComponent<Rigidbody2D>();

                float angle2 = 5f * Mathf.Deg2Rad;
                rigidR2.AddForce(transform.up * 10 + transform.right * Mathf.Tan(angle2) * 10, ForceMode2D.Impulse);
                rigidC2.AddForce(Vector2.up * 10, ForceMode2D.Impulse);
                rigidL2.AddForce(transform.up * 10 + transform.right * Mathf.Tan(-angle2) * 10, ForceMode2D.Impulse);
                break;
        }
    }

    private void OnTriggerEnter2D(Collider2D collision)
    {
        if (collision.gameObject.tag == "Enemy" || collision.gameObject.tag == "EnemyBullet"/* && !isDead*/)
        {
            if (isHit)
                return;

            isHit = true;
            life--;
            Debug.Log("현재 생명: " + life);
            gameManager.UpdateLifeIcon(life);
            Debug.Log("UpdateLifeIcon 호출됨!");

            if (life == 0)
            {
                gameManager.GameOver();
            }
            else
            {
                gameManager.RespawnPlayer();
            }
            gameObject.SetActive(false);
            gameManager.RespawnPlayer();
            //gameManager.StartCoroutine(gameManager.RespawnPlayer());
            //StartCoroutine(HandleDeath());
        }
        else if (collision.gameObject.tag == "Item")
        {
            Item item = collision.gameObject.GetComponent<Item>();
            switch (item.type)
            {
                case "Coin":
                    score += 100;
                    break;
                case "Power":
                    if (power == maxPower)
                        score += 500;
                    else
                        power++;
                    break;
                case "Boom":
                    if (boom < maxBoom)
                        boom++; // 최대치 이내에서 증가
                    break;
            }
            collision.gameObject.SetActive(false); // 오브젝트 풀링으로 인한 변경
        }
    }

}

Bullet & Energy Bullet - ObjectPool 로 인한 변경

bullet Scipt

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Bullet : MonoBehaviour
{
    public int dmg;
    private void OnTriggerEnter2D(Collider2D collision)
    {
        if(collision.gameObject.tag == "BorderBullet")
        {
            gameObject.SetActive(false);
        }
        else if(collision.gameObject.tag == "Enemy")
        {
            gameObject.SetActive(false);
        }

    }
}

EnergyBullet

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class EnergyBullet : MonoBehaviour
{
    public int dmg;
    private void OnTriggerEnter2D(Collider2D collision)
    {
        if(collision.gameObject.tag == "BorderBullet")
        {
            gameObject.SetActive(false);
        }
    }
}

오브젝트 매니저 생성.

ObjectManager

GameManager의 오브젝트매니저 관리

GameManager

Player의 게임매니저, 오브젝트매니저 가져오기

 

'개발일지 > Journey to West' 카테고리의 다른 글

Background  (0) 2025.05.13