序
某所で ObjectPool の話題が出ていたが、大体GameObjectでのpoolになっているが、
クラス指定できないと毎度GetComponent する羽目になる。
↓
イケてない
UniRx の Object Pool 使えばよくね
↓
プール用クラス書くのめんどくさくね
という事で書いてみた。
要件
- ObjectPool
- 型指定できる
- 一応、UniRx使わない方向で(UniRx.tools のプール使えばいいので)
本体
コピペでOK
SimpleObjectPool.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SimpleObjectPool<T> where T : MonoBehaviour
{
// Public Static
public static SimpleObjectPool<T> Instance;
// Private
T prefabBase;
int ObjectCnt = 0;
Transform poolBehaviour;
Queue<T> pool = new Queue<T>();
int createCount = 0;
public SimpleObjectPool(T prefab, int objectCount = 100)
{
Instance = this;
prefabBase = prefab;
ObjectCnt = objectCount;
var go = new GameObject("SimpleObjectPool");
GameObject.DontDestroyOnLoad(go);
poolBehaviour = go.transform;
}
public T Rent()
{
if (pool.Count == 0)
{
CreateNewObject();
}
var obj = pool.Dequeue();
obj.gameObject.SetActive(true);
return obj;
}
public void Return(T obj)
{
obj.gameObject.SetActive(false);
pool.Enqueue(obj);
}
public void Update()
{
if (createCount < Instance.ObjectCnt)
{
CreateNewObject();
}
}
void CreateNewObject()
{
var newObj = GameObject.Instantiate(Instance.prefabBase) as T;
newObj.transform.SetParent(Instance.poolBehaviour);
newObj.name = newObj.name + $"{createCount}";
newObj.gameObject.SetActive(false);
Instance.pool.Enqueue(newObj);
createCount++;
}
}
使い方
Inspector
シーンの最初からあるGameObjectとかに、
エディタ上からプールに指定したいプレハブなどを設定しておく
public DummyEnemy enemyPrefab = default;
初期化
SimpleObjectPool クラスを型指定で新規作成。
以降は、シングルトンなので、SimpleObjectPool.Instance でどこからでもアクセスできる。
void Start()
{
var pool = new SimpleObjectPool<DummyEnemy>(enemyPrefab);
}
オブジェクト生成
一度にまとめて作成してもいいが、フレームごとに1つづつ作ったほうがお行儀が良いので。
void Update()
{
SimpleObjectPool<DummyEnemy>.Instance.Update();
}
借りて、返す
// 借りる
var obj = SimpleObjectPool<DummyEnemy>.Instance.Rent();
// 返す
SimpleObjectPool<DummyEnemy>.Instance.Return(obj);
実際どうなの?
車輪の再開発とはまさにこのこと。多分自分用。
Updateの部分を observable にすれば、初期化だけで綺麗にUpdateできるね!
それだと最初からUniRxツール使えよという話。
ゴミですね。
供養(-人-)チーン