[TIL] Unity - 오브젝트 풀 예외 처리

MINO·2024년 8월 12일
post-thumbnail

2024-08-12


예외 처리

프로그램 실행 중 발생할 수 있는 오류를 관리하는 기법 중 하나이다.

예외가 발생하였을 때, 프로그램이 중단되지 않고 적절한 방법으로 오류를 처리할 수 있도록 하여 프로그램의 안정성과 신뢰성을 높일 수 있다.


문제 상황

오브젝트 풀에 사용되지 않는 아이템 (몬스터의 전리품) 객체가 있음에도
정상적으로 꺼내지지 않아 NullReferenceException 오류가 발생

  1. 오브젝트 풀에서 생성해둔 몬스터, 아이템을 꺼내 사용
  2. 몬스터 hp 가 0 이 되면, 아이템을 먼저 드랍한 뒤, 오브젝트 풀에 반환되는 형태
  3. 오브젝트 풀에 사용중이지 않은(비활성화 상태인) 아이템 객체가 남아 있음


문제 원인

유저가 아이템을 픽업하지 않았을 때, 시간이 지나도 반환되는 코드가 없다.

오브젝트 풀은 Dictionary<string, Queue<GameObject>> 를 사용하여
GameObject 를 선입선출 기법으로 꺼내 사용하고 반환한다.

미리 생성해둔 오브젝트 풀의 아이템의 한 사이클을 돌아왔지만
먼저 생성된 아이템이 반환되지 않아 오브젝트 풀에서 꺼낸 아이템 객체가 Null 이었던 것이다.

반면에, 몬스터 스포너 스크립트에는 오브젝트 풀에서 꺼낸 몬스터 객체가 Null 인 경우,
일시적으로 몬스터 스폰을 멈추고 일정 시간 이후 다시 몬스터를 생성하는 예외 처리가 있었다.

[Monster Spawn]

GameObject monster = ObjectPool.Instance.SpawnFromPool(monsterType);

if (monster != null)
{
    monster.transform.position = randomPos;
    monsterSpawnPos.Add(randomPos);

    monster.SetActive(true);
}
[Item Spawn]
 private void SetItem(ItemData data, GameObject monsterObj)
 {
     GameObject createItem = ObjectPool.Instance.SpawnFromPool("Item");

     createItem.GetComponent<SpriteRenderer>().sprite = data.IconSprite;

     createItem.GetComponent<CreateItemData>().SetItemData(data);

     createItem.transform.position = monsterObj.transform.position;

     createItem.SetActive(true);
 }

해결

오브젝트 풀의 아이템 스폰시, 예외 처리 코드를 추가해주었다.

public GameObject SpawnFromPool(string tag)
{
	if (!PoolDictionary.ContainsKey(tag)) return null;

	GameObject obj = PoolDictionary[tag].Dequeue();
	PoolDictionary[tag].Enqueue(obj);

	if (obj.activeInHierarchy && tag != "Item")
 	{
	// 몬스터의 경우, null 반환
	return null;
	}

	// 아이템의 경우, 가장 오래된 오브젝트 반환
	return obj;
}

TIL 마무리

개발을 거의 마무리하는 단계에서,
버그가 하나 발생할 때마다 마음이 철렁인다.
유저 테스트 때, 버그를 발견하는 것보단 나을테니
최대한 빨리 버그를 다 잡고 싶다.

profile
안녕하세요 게임 개발하는 MINO 입니다.

0개의 댓글