https://qiita.com/Akira_Kido_N/items/b5fa0c1ef324e57b0c28
3 年前の記事が未だにたまに LGTM とかされているので、一応今の自分だったらどう作るかなーと思って考えてみました。
以下になります。
publicclassObjectPool:MonoBehaviour{[SerializeField]privateGameObjectprefab;privatereadonlyQueue<GameObject>_cache=newQueue<GameObject>();/// <summary>/// オブジェクトのインスタンスを取得します。/// キャッシュが無い場合、新しく生成します。/// </summary>/// <typeparam name="T"></typeparam>/// <returns></returns>publicTGetOrCreate<T>()whereT:Component{GameObjectresult;if(_cache.Count>0){result=_cache.Dequeue();}else{result=Instantiate(prefab);varret=result.AddComponent<ObjectPoolReturn>();ret.ObjectPool=this;}result.SetActive(true);returnresult.GetComponent<T>();}publicvoidReturnToPool(GameObjectgo){_cache.Enqueue(go);}}position とか設定してましたが、それは呼び出し元のオブジェクトで好きにしてね、という感じ。インスタンスを取得して GetComponent するだけ。場合によっては GetComponent しないメソッドも追加していい気もする。
ObjectPoolReturnはこんな感じ
publicclassObjectPoolReturn:MonoBehaviour{[CanBeNull]publicObjectPoolObjectPool{privateget;set;}privatevoidOnDisable(){if(ObjectPool!=null){ObjectPool.ReturnToPool(gameObject);}}}基本的に、プールで使うオブジェクトは Startではなく OnEnableで初期化して、インスタンスを消す場合は gameObject.SetActive(false);しておけばオブジェクトプールを意識しなくていいって感じ。
とは言え、今オブジェクトプールを使うかと聞かれると微妙。ハードウェアのスペックが上がってるので Instantiate 自体がそんなに遅くないし、そこまで気にするなら ECS 使った方が絶対いい。