🐥
Unityでもっと簡単☆オブジェクトプール
Qiitaより転載
2020/4/29 初投稿
3 年前の記事が未だにたまに LGTM とかされているので、一応今の自分だったらどう作るかなーと思って考えてみました。
以下になります。
public class ObjectPool : MonoBehaviour
{
[SerializeField] private GameObject prefab;
private readonly Queue<GameObject> _cache = new Queue<GameObject>();
/// <summary>
/// オブジェクトのインスタンスを取得します。
/// キャッシュが無い場合、新しく生成します。
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public T GetOrCreate<T>() where T : Component
{
GameObject result;
if (_cache.Count > 0)
{
result = _cache.Dequeue();
}
else
{
result = Instantiate(prefab);
var ret = result.AddComponent<ObjectPoolReturn>();
ret.ObjectPool = this;
}
result.SetActive(true);
return result.GetComponent<T>();
}
public void ReturnToPool(GameObject go)
{
_cache.Enqueue(go);
}
}
position とか設定してましたが、それは呼び出し元のオブジェクトで好きにしてね、という感じ。インスタンスを取得して GetComponent するだけ。場合によっては GetComponent しないメソッドも追加していい気もする。
ObjectPoolReturn
はこんな感じ
public class ObjectPoolReturn : MonoBehaviour
{
[CanBeNull] public ObjectPool ObjectPool { private get; set; }
private void OnDisable()
{
if (ObjectPool != null)
{
ObjectPool.ReturnToPool(gameObject);
}
}
}
基本的に、プールで使うオブジェクトは Start
ではなく OnEnable
で初期化して、インスタンスを消す場合は gameObject.SetActive(false);
しておけばオブジェクトプールを意識しなくていいって感じ。
とは言え、今オブジェクトプールを使うかと聞かれると微妙。ハードウェアのスペックが上がってるので Instantiate 自体がそんなに遅くないし、そこまで気にするなら ECS 使った方が絶対いい。
Discussion