public class Poolable : MonoBehaviour
{
public bool IsUsing;
}
단순히 풀링할 오브젝트인지 구분하기 위해 오브젝트에 부착할 스크립트이다.
// Pool 클래스는 @Pool_Root 산하에 있다.
// Pool 클래스는 Root go와 Original go 그리고 Stack을 가진다.
class Pool
{
public GameObject Original { get; private set; }
public Transform Root { get; set; }
Stack<Poolable> _poolStack = new Stack<Poolable>();
public void Init(GameObject original, int count = 5)
{
Original = original;
Root = new GameObject().transform;
Root.name = $"{original.name}_Root";
for (int i=0; i<count; i++)
Push(Create());
}
// original 게임오브젝트를 생성하고 poolable 컴포넌트 부착.
Poolable Create()
{
GameObject go = Object.Instantiate<GameObject>(Original);
go.name = Original.name;
return go.GetOrAddCompoent<Poolable>();
}
// poolable이 붙은 오브젝트를 비활성화한채로 "original_Root"에 추가.
// 스택에도 추가한다.
public void Push(Poolable poolable)
{
if (poolable == null)
return;
poolable.transform.parent = Root;
poolable.gameObject.SetActive(false);
poolable.IsUsing = false;
_poolStack.Push(poolable);
}
// 스택에 있는 것을 가져온다.
// 없으면 새로 만듦
public Poolable Pop(Transform parent)
{
Poolable poolable;
if (_poolStack.Count > 0)
{
poolable = _poolStack.Pop();
}
else
poolable = Create();
poolable.gameObject.SetActive(true);
poolable.transform.parent = parent;
poolable.IsUsing = true;
return poolable;
}
}
Pool 클래스이다.
풀링할 GameObject인 Original과 게임오브젝트의 부모 오브젝트로 사용할 Root를 가진다.
그리고 각 클래스는 Poolable 컴포넌트를 스택으로 가진다.
Create() 함수는 Original을 생성하고 poolable 컴포넌트를 부착한다.
Push() 함수는 Create()로 생성한 Original을 부모 산하로 넣고, 비활성화 후 스택에 넣는다.
Pop() 함수는 스택에 있는 것을 가져온다. 없으면 새로 생성.
Init() 함수에서 original및 부모를 설정하고 count 수만큼 Create및 Push한다.
Dictionary<string, Pool> _pool = new Dictionary<string, Pool>();
Transform _root;
// @Pool_Root 오브젝트 생성
public void Init()
{
if (_root == null)
{
_root = new GameObject { name = "@Pool_Root" }.transform;
Object.DontDestroyOnLoad(_root);
}
}
최상위 _root 오브젝트 생성
public void CreatePool(GameObject original, int count = 5)
{
Pool pool = new Pool();
pool.Init(original, count);
pool.Root.parent = _root;
_pool.Add(original.name, pool);
}
새로운 pool 클래스를 생성하고 클래스의 Root를 최상위 _root오브젝트로 이동.
딕셔너리에 추가.
public void Push(Poolable poolable)
{
string name = poolable.gameObject.name;
if (_pool.ContainsKey(name) == false)
{
GameObject.Destroy(poolable.gameObject);
return;
}
_pool[name].Push(poolable);
}
클래스에 접근해서 클래스 내의 스택에 poolable을 push
public Poolable Pop(GameObject original, Transform parent = null)
{
if (_pool.ContainsKey(original.name) == false)
CreatePool(original);
return _pool[original.name].Pop(parent);
}
사전에서 Pool클래스에 접근, 만약 없는 경우 새로 만든다.
그리고 pool클래스에서 Pop함수를 통해 poolable 컴포넌트를 반환
public GameObject GetOriginal(string name)
{
if (_pool.ContainsKey(name) == false)
return null;
return _pool[name].Original;
}
사전에서 pool클래스에 접근해서 Original 게임오브젝트를 반환
public void Clear()
{
foreach (Transform child in _root)
GameObject.Destroy(child);
_pool.Clear();
}
최상위 _root의 자식들을 모두 Destroy하고 사전또한 비운다.