PoolManager
32ドル。AssetStoreにたくさんのObject Pool Scriptが販売されているけど皆10ドルくらい。32ドルは破格の値段だ
アセットストア
https://www.assetstore.unity3d.com/jp/?#!/content/1010
ドキュメント
http://poolmanager.path-o-logical.com/
特徴
Pool Instance
PoolInstance。これにはInstantiate/Destroy関数の代わりとなるSpawn/Despawn関数が用意されている。これを使うことでGCを回避する
Pool Pre-Runtime Instanceを設定することで事前にシーン上に配置しておくPoolInstance数を決定できる。
簡単なセットアップ
SpawnPoolコンポーネントをもったPoolManager GameObjectをシーンに配置する。
あと
Instantiate関数 -> Spawn関数
Destroty関数 -> Despawn関数
に置き換える。
uGUI,Audio,Particle SystemもPool可能
使ってみる
セットアップ
Documentを参考に
Documentが割と丁寧に書いてあるのでうれしい。
http://docs.poolmanager.path-o-logical.com/home/1-start-pooling-spawn-despawn
Pool管理用に適当なGameObjectを作成し、SpawnPoolコンポーネントをAddする。
SpawnPoolコンポーネントのPoolNameパラメータに適当な名前を付ける。
- Match Pool Scale PoolObject生成時にPoolObjectのLocalScaleを1にするか
- Match Pool Layer PoolObject生成時にPoolObjectとその子要素のLayerをSpawnPoolコンポーネントを持つGameObjectのLayerと同じにするか
- Don't Destroy On Load SpawnPoolコンポーネントとPoolしているGameObjectをDontDestoryOnLoadにするか。既に同じSpawnPoolオブジェクトがDontDestoryOnLoadされているかどうかに限らずこのフラグがOnだとDontDestoryOnLoadされる。 タイトルシーンでDontDestoryOnLoadしてて、ゲームシーンでPool使った後にまたタイトルシーンに行くとSpawnPoolオブジェクトが増えている気がする。
とりあえずセット
適当なCubeのPrefabを作成し、Pre-Prefab-Poolにセット。preload Amountに10をセットしてゲーム起動時に10個ほど生成されるようにした。
PoolNameにTestCubeと入力。
ゲーム再生。
ちゃんと10個Insntanceが作られた。(InActive)
PoolされたPrefabをSpawnする
public GameObject cubePrefab;
Transform poolInstance;
// Use this for initialization
void Start()
{
var spawn = PoolManager.Pools["TestCube"];
var cube = spawn.Spawn(cubePrefab);
poolInstance = cube;
}
SpawnしたPrefabをDespawnする
void Update()
{
if (Input.GetKeyUp(KeyCode.Space))
{
if (PoolManager.Pools["TestCube"].IsSpawned(poolInstance))
{
PoolManager.Pools["TestCube"].Despawn(poolInstance);
}
}
}
メンバ変数であるpoolInstanceにspawnさせたPrefabのインスタンスをセットしていたけど、こいつを使ってNullチェックしてはいけない。Despawnした後もこいつのInstanceは削除されないのでnullにはならないからだ。代わりにPoolManager.Pools["hoge"].IsSpawned(pooledobj)を使用する。
//悪い
if(poolInstance != null)
{
//hogehoge
}
//良い
if (PoolManager.Pools["TestCube"].IsSpawned(poolInstance))
{
//hogehoge
}
大量にSpawnさせてみる。
SpaceKeyを押したときにSpawnさせるようにした。
PreLoad数を超えてSpawnすると新しいPrefabInstanceが用意される。
Spawnする順番
PreLoadしたPrefabの各InstanceはPreLoadさせたSpawnPoolオブジェクトの子要素になる。Spawn関数が呼ばれた場合はPreLoadした順で(子要素のIndex0から)Instanceが返される。ただし一度使ったInstanceの取得順は最後に回される。
Spawn/Despawn時の初期化/終了処理
適当なコンポーネントにOnSpawned/OnDespawned関数を付けてCubePrefabにAddする。
内部でBroadcastMessageをしている。これで初期化・終了処理ができる。
using PathologicalGames;
public class TestCube : MonoBehaviour {
private void OnSpawned(SpawnPool pool)
{
Debug.Log
(
string.Format
(
"OnSpawnedExample | OnSpawned running for '{0}' in pool '{1}'.",
this.name,
pool.poolName
)
);
}
private void OnDespawned(SpawnPool pool)
{
Debug.Log
(
string.Format
(
"OnSpawnedExample | OnDespawned unning for '{0}' in pool '{1}'.",
this.name,
pool.poolName
)
);
}
}