오브젝트 풀 응용
모바일 기기에서 Instantiate와 Destroy 로 인한
GC 의 폭주를 막기 위해서 주로 쓰는 기법 중에
오브젝트 풀이라는 것이 있다.
(이걸 접한건 2년 전 쯤인데 , 혼자서 액션 클리커 비스무리 한 것을 만들 때다. )
인터넷에 돌아다니는 유니티 예제코드는 보통
List
꺼내서 켜서 사용하고 , 다 사용하면 다시 리스트에 꺼서 넣어서 보관하는 식으로
오브젝트를 삭제하지 않고 활성화&비활성화로 이용하는 것이다.
생성과 삭제로 GC 가 한번에 우르르 삭제하는 것이아니라 ,
계속 비활성화 상태로라도 들고 있음으로써 삭제 못하게 하는 것으로 알고있다.
이번에 사장님의 요청으로 Pvp 개발을 빌미로 일종의 전투 메커니즘 리팩토링을 하고 있는데
( 같은 기능 + 추가기능 & 나은 효율 * 새로 짜서 Pvp 에 우선 구현하고 , 안정성 생기면 나중에 기존 필드에도 교체해서 확장 )
요청은 대략 다음과 같았다.
- 검기 같은 이펙트는 무한대로 생성할 필요가 없고 ( 그래서 기존 코드가 과부하를 불러왔다 , 부족할 시 ) , 미리 설정한 한정 갯수를 넘으면 이미 활성화 상태인 ( 작동중인 이펙트) 오브젝트를 가져와서 초기화 한후 그냥 바로 사용한다 ( 돌려쓰기 )
내가 만들고 싶었던 사항은 다음과 같다.
- 전보다 성능 상 이점을 가졌으면 좋겠다.
- MonoBehaviour 를 상속 받지 않아서 new 로 생성할 수 있는 , 씬을 건드리지 않아도 되는 클래스를 만들자.
만들다보니 추가된 부분
- 검기 이펙트와 , 피격 이펙트는 조금 달라서 하나는 유저의 오브젝트 안에 자식으로 넣어야 했지만, 다른 하나는 그러지 않는 편이 바람직했다. 그래서 오버로드를 사용해서, 부모가 될 트랜스폼을 생성자에 인자로 넣지 않으면 애초에 자식으로 편입되지 않게 했다. ( 부끄럽지만 약간 //hack ..)
public class EffectObjectPool { List
ActiveObjects = new List (); Stack
InactiveObjects = new Stack (); Vector3 originScale;
public EffectObjectPool( GameObject targetObject, int poolLength)
public EffectObjectPool(Transform playerTransform ,GameObject targetObject, int poolLength)
public GameObject GetObject()
public void RetireObject(GameObject obj)
}
위 처럼 대략 끝났다.
세부 사항은 회사 기밀(?) 일 것 같아서
이름과 인자만 남겼다.
만들고나니 아쉬운 점
- 이펙트를 만들긴 만들었는데 ,오브젝트 히에라키 (위계구조) 창을 보면 끔찍하다 . 80 개의 오브젝트로 이루어진 풀이면 80 개 오브젝트가 늘어져있어서 … 바람직한 해결법은 부모 오브젝트 하나 만들고 다 입양시키는 것 (?)
- RetireObject() 를 호출하는 시점이 , 당연히 애니메이션의 끝이나 다 보여준 후여야 하는데 , 이를 코루틴으로 하기에는 내키지 않고, Update() 류는 끔찍한 일이라고 생각하며 , Itween.SetInterval().SetCallback() 으로 해결했는데, Tween 내부 로직을 모르니 맞는지는 잘 모르겠지만, 잘돌아가긴 한다. 바람직한 해결방법은 지난번에 하기로한 Tween 내부 구현을 공부하는 것. 일단 캘린더에 등록해둬야겠다.