스파르타 게임개발종합반(Unity)/TIL - 본캠프 매일 공부 기록

2024.06.21 TIL - 이벤트 구독 취소의 중요성

테크러너 2024. 6. 21.

아이템 스폰이 Max값보다 오버되어 스폰되는 문제

맵에 아이템을 최대 10개까지만 생성하고 싶었다.

그런데 플레이어가 아이템을 빠르게 주우니까 최대 10개보다 더 아이템이 생성되는 문제 가 발생했다.

 

    private IEnumerator SpawnItemsWithInterval()
    {
        while (true)
        {
            yield return new WaitForSeconds(SpawnTime);
            
            if (CurItemsOnMap < MaxItemsOnMap)
            {
                Debug.Log("IEnumerator: " + CurItemsOnMap);
                SpawnItems();
            }
        }
    }
    
    private void SpawnItems()
    {
        if (CurItemsOnMap >= MaxItemsOnMap)
        {
            Debug.LogWarning("Reached maximum item count.");
            return;
        }

        Vector3 spawnPos = ReturnRandPos();
        Pool spawnPool = ReturnRandPool();

        if (spawnPool != null)
        {
            GameObject spawnedObject = ObjectPoolManager.Instance.GetObject(spawnPool.Prefab.name);
            if (spawnedObject != null)
            {
                spawnedObject.transform.position = spawnPos;
                CurItemsOnMap++;
                spawnedObject.GetComponent<ItemPickUp>().OnPickUp += () => CurItemsOnMap--;
            }
            else
            {
                Debug.LogWarning("Failed to get object from pool: " + spawnPool.Prefab.name);
            }
        }
    }

로직을 아무리 들여다 봐도 문제가 없다고 생각했다.

그냥 아이템을 빨리 먹어서 문제겠거니 생각하고 스폰주기나 if문 조건 등을 수정하기만 했다.

그래도 고쳐지지 않았다.

 

 

이벤트 구독 취소의 중요성

spawnedObject.GetComponent<ItemPickUp>().OnPickUp += () => CurItemsOnMap--;

맵에 아이템이 Max값보다 더 설정되니까 `CurItemOnMap`이 문제가 있는게 분명하다.

아니나 다를까 `OnPickUp` 이벤트를 구독해둔 코드가 있었고, 아이템은 오브젝트 풀링으로 관리를 하고 있었기 때문에 아이템이 파괴되지 않는 이상 이벤트는 계속 구독상태라서 `CurItemsOnMap`이 계속 감소 되고 있던 것이다.

 

    private void OnDisable()
    {
        OnPickUp = null;
    }

그래서 아이템 코드로 가서 이벤트 구독을 취소하니 문제가 해결됐다.

 

C언에서 동적할당 후 해제를 꼭 하고, C++에서 생성자와 소멸자를 꼭 넣는 것처럼 이벤트도 구독을 했다면 꼭 취소를 하는 습관을 들여야한다..! 진짜.. 중요하다..!

반응형

댓글