using System.Collections.Generic;
using System.IO;
using System.Linq;
using UnityEngine;
/// <summary>
/// ๊ฐ๋จํ ๋ฒ์ฉ ์ค๋ธ์ ํธ ํ
/// </summary>
/// <typeparam name="T">ํ์์ ๋ฐ๋ก ๊บผ๋ด์ ์ฌ์ฉํ ์ปดํฌ๋ํธ ํ์
</typeparam>
public class SimpleObjectPool<T> where T : MonoBehaviour
{
private readonly Transform objHolder;
private readonly T targetPrefab;
private readonly List<T> usingPool = new List<T>();
private readonly List<T> sleepingPool = new List<T>();
public SimpleObjectPool(T objToUse, Transform objHolder, int preWarmCount = 5)
{
targetPrefab = objToUse;
this.objHolder = objHolder;
PreWarm(preWarmCount);
}
/// <summary>
/// ํ์ ์ํ๊ฐ ์ ์์ ์ธ์ง ์ฒดํฌํจ
/// ๋ง์ฝ ๋น์ ์์ ์ด๋ผ๋ฉด ํ์ ์ ๋ฆฌํ๋ ๊ธฐ๋ฅ๋ ๊ฒธํจ
/// </summary>
/// <returns>true : ์ ์</returns>
public bool CheckPoolStatus()
{
var ret = objHolder && targetPrefab;
if (ret) return true; //์ ์์ ์ด์ง ์์ ๊ฒฝ์ฐ ๋ฆฌ์คํธ๋ฅผ ์ ๋ฆฌํจ
usingPool.Clear();
sleepingPool.Clear();
return false;
}
/// <summary>
/// ์ค๋ธ์ ํธ๋ฅผ ๋ฏธ๋ฆฌ ์ถ๊ฐ๋ก ์์ฑํ ์ ์๋ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋ method
/// </summary>
/// <param name="countToGenerate">๋ฏธ๋ฆฌ ์ถ๊ฐ๋ก ์์ฑํ ์ค๋ธ์ ํธ ์</param>
public void PreWarm(int countToGenerate)
{
GenerateObjects(countToGenerate);
}
/// <summary>
/// ์ค๋ธ์ ํธ๋ฅผ ๋ช
์์ ์ผ๋ก ํ์ ๋ฐํํจ
/// </summary>
/// <param name="obj">sleeping pool์ ๋ฐํํ ์ค๋ธ์ ํธ</param>
public void ReturnObject(T obj)
{
obj.gameObject.SetActive(false);
if (!usingPool.Remove(obj)) //ํ์ ์ํด ์ ์ด๋์ง ์๊ณ ์๋ ์ค๋ธ์ ํธ๋ฅผ ๋ฐํ ์๋ํ๋ ๊ฒฝ์ฐ ์์ธ ๋ฐ์
throw new InvalidDataException();
sleepingPool.Add(obj);
}
/// <summary>
/// ์ค๋ธ์ ํธ๋ฅผ ๋ฏธ๋ฆฌ ์์ฑํจ
/// </summary>
/// <param name="count"> ์์ฑํ ์ค๋ธ์ ํธ ์ </param>
private void GenerateObjects(int count = 5)
{
for (var i = 0; i < count; i++)
{
var newObj = Object.Instantiate(targetPrefab.gameObject, objHolder).GetComponent<T>();
newObj.gameObject.SetActive(false);
sleepingPool.Add(newObj);
}
}
/// <summary>
/// ๋ฏธ์ฌ์ฉ ์ค๋ธ์ ํธ๋ฅผ ๊ฐ์ ธ์ ํ์ฑํํ๊ณ ๋ฐํํจ
/// </summary>
/// <param name="getNonActivated"> ์ค๋ธ์ ํธ๋ฅผ ํ์ฑํ๋์ง ์์ ์ฒด๋ก ๋ฐํ </param>
/// <returns> ํ์ฑํ๋ ์ค๋ธ์ ํธ </returns>
public T GetObj(bool getNonActivated = false)
{
if (sleepingPool.Count == 0)
{
if (!ClearUsingPool())
GenerateObjects();
}
var retObj = sleepingPool[0];
sleepingPool.Remove(retObj);
usingPool.Add(retObj);
if (!getNonActivated)
retObj.gameObject.SetActive(true);
return retObj;
}
private readonly List<T> tempList = new List<T>();
/// <summary>
/// ํ์ ๋ฌด๊ฒฐ์ฑ์ ์ ์งํ๊ธฐ ์ํด ๋ฏธ์ฌ์ฉ ์ค์ธ ์ค๋ธ์ ํธ๊ฐ ์ฌ์ฉ ์ค ํ์ ์๋ ๊ฒฝ์ฐ ์ ๋ฆฌํจ
/// </summary>
/// <returns> ์ฒญ์๋ ์ค๋ธ์ ํธ๊ฐ ์๋์ง (์์ผ๋ฉด false, ์์ผ๋ฉด true) </returns>
private bool ClearUsingPool()
{
tempList.Clear();
tempList.AddRange(usingPool.Where(obj => !obj.gameObject.activeSelf));
sleepingPool.AddRange(tempList);
usingPool.RemoveAll(tempList.Contains);
return tempList.Count != 0;
}
}
๋ฒ์ฉ์ผ๋ก ๋ง๋ค์ด๋๊ณ ์ ์ฐ๊ณ ์๊ธด ํ๊ฑฐ๋
๊ทผ๋ฐ ์ค๋ธ์ ํธ ํ๋ง ํน์ฑ ์ ์๋ค์ด๊ฐ๋ ํ๋ก์ ํธ๊ฐ ๋๋ฌผ๋ค ๋ณด๋ ๋ ๊ด์ฐฎ๊ฒ ๋ค๋ฌ์ด๋ณด๊ณ ์ถ์ด์
์๊ฒฌ ๋ฌผ์ด๋ณด๋ฌ ์์
์ถ๊ฐ ๊ธฐ๋ฅ, ์ฑ๋ฅ ์ ๊ฐ์ ์ ์๊ฒฌ ๋ฐ์
์ธ๋ถ์ด๋ค์ ๋ ์ ๋ง๋ค์ด์ ์ฐ๊ณ ์๊ฒ ์ง๋ง ์ฐ๊ณ ์ถ์ ์ฌ๋์ ๊ฐ์ ธ๋ค ์จ๋ผ
checkPoolStatus๋ clearUsingPool ์ด์ํจ. objectPool ์์ฒด๊ฐ ๋ฌธ์ ๊ฐ ์๋ค๋ฉด ํ์์๋๋ฐ ํจ์์ธ๋ฐ? checkPoolStatus๋ ํจ์ ์ด๋ฆ๊ณผ ๋ค๋ฅด๊ฒ ์ค๋ธ์ ํธ ํ์ ๋น์ฐ๋ ์ญํ ์ด์ง ์๋? ๋ฆฌ์คํธ์์ ์ค๋ธ์ ํธ๊ฐ ๋ค์ด์์ผ๋ฉด ๋ฆฌ์คํธ๋ง ๋น์ฐ๋ฉด ๋๋๊ฒ ์๋๋ผ ์ค๋ธ์ ํธ ์ ๊ฑฐ๋ ํด์ผํ ํ ๋ฐ?
๊ทธ๋ฆฌ๊ณ ์ค๋ธ์ ํธํ์ ์ฌ์ฉํ ๊ปใด monobehaviour์ ๊ทธ๋๋ก ์์๋ฐ๊ธฐ๋ณด๋ค ๋ฉํํด์ ์ฐ๋๊ฒ ๋์ ์๋ ์์
์ค๋ธ์ ํธ ์ ๊ฑฐ๋ ๋ด๊ฐ ๋์ณค๋ ๋ถ๋ถ์ด ๋ง๋ ๊ฒ ๊ฐ๋ค. ์ ๊ฒ ์ฌ์ด ๋ณ๊ฒฝ๋์ ๋ ์คํฌ๋ฆฝํฐ๋ธ ์ค๋ธ์ ํธ์ชฝ์์ ์ฐ๋ ํ์์ ๋ฌธ์ ๊ฐ ์๊ธด ์ ์ด ์์ด์ ๋ฃ์ด ๋์ ๊ฑฐ์. check์ ์ ๋ฆฌ๊น์ง ๋ชฐ์ ๋์ ๊ฑด ์ด์งํผ ๋น์ ์์ ์ธ ์ํ๋ผ๋ฉด ์ฌ์ฉํ์ง ๋ชปํ๊ธฐ ๋๋ฌธ์ ํจ๊ป ๋ ๊ฑด๋ฐ ๋ช ํํ ํ๋ ค๋ฉด ์ฌ์ค ๋ถ๋ฆฌ ํ๋ ๊ฒ ๋ง๊ธด ํ์ง ใ ใ .
clearUsingPool์ ๋ง๋ค์ด ๋์ ์ด์ ๊ฐ ์ค๋ธ์ ํธ๋ฅผ ์ฌ์ฉํ๋ ์ฃผ์ฒด๊ฐ ํ์ด ์๋๋ผ ์ธ๋ถ์ ์๊ธฐ ๋๋ฌธ์ ์ฌ์ฉํ๊ณ ๋๋ ค๋๋ ์ฑ ์์ ์ฌ์ฉํ๋ ์ชฝ์ ๋๊ธฐ ๋๋ฌธ์. ๊ทธ๋ฌ๋ค ๋ณด๋ usingPool์ ์ค๋ธ์ ํธ๋ฅผ ๋ฆฌ์คํธ์ ๊ฐ๊ณ ์๊ธด ํ์ง๋ง ์ด๊ฒ ์ด๋ป๊ฒ ์ฌ์ฉ๋๋์ง๋ ํ์์ ํ๋จํ ๋ฐฉ๋ฒ์ด ์์. ๊ทธ๋์ ํ์ํ ํจ์์ ์ค๋ธ์ ํธ๊ฐ ๋ชจ์๋ ๋ ์๋ก ๋ง๋๋ ๊ฒ ๋ณด๋ค๋ usingPool์ ํน์๋ผ๋ ๋๊ณ ์๋ ์ค๋ธ์ ํธ๊ฐ ์์ผ๋ฉด ์ค์บํด์ ์ฐพ์ ๋ณด๊ณ ๊ทธ๊ฑธ ์ฌ์ฉํ๋ ๊ฒ ๋ ์ธ๊ฒ ๋จนํ๊ธฐ๋ ํ๊ณ .
๊ทธ๋ฆฌ๊ณ mono๋ ์ ๋ค๋ฆญ ํ์ ์๋ผ ์์๊ณผ ๋ฌด๊ดํจ
๋ด๊ฐ ํ์ฌ ์ฌ๋ฌ๊ตฐ๋ฐ ๋ค๋๋ฉด์ ์ ๋ฐ ์ง ํ์ ์ด ํ๋ฒ๋ ์๊ณ ํ๋ ๊ฒ๋ ๋ณธ์ ์ด ์๋๋ฐ
mono๋ ์๋ฅผ๋ค์ด KMonoBehaviour : MonoBehaviour๊ฐ์ด ํ๋ก๊ทธ๋๋จธ๊ฐ ๊ด๋ฆฌํ๋ ๋ชจ๋ ธ ๊ฐ์ฒด๋ก ๋ง๋ค๋ผ๋ ์๋ฏธ์์. ์ค๋ธ์ ํธ ํ์ ์ฌ์ฉํ๋ค๋ ๊ฒ ์์ฒด๊ฐ ํ๋ก๊ทธ๋๋จธ๊ฐ ๊ณ์ ๊ด๋ฆฌํด์ค์ผํ๋๊น
๋๋ง ์ฐ๋๊ฒ ์๋๋๊น ์ผ์ข ์ ๋ณดํ์ด๋ผ๊ณ ์๊ฐํ๋ฉด ๋ ๊ฒ ๊ฐ๋ค
where ํค์๋๋ฅผ ์ฒ์๋ดค๋๋ฐ ๋๋ถ์ ๊ณต๋ถํ๋ค