5
7

More than 5 years have passed since last update.

Unity Asset PoolManager使ってみた

Posted at

PoolManager
32ドル。AssetStoreにたくさんのObject Pool Scriptが販売されているけど皆10ドルくらい。32ドルは破格の値段だ
2017-02-26 20.53.19.jpg

アセットストア
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と入力。
2017-02-26 23.51.32.jpg

ゲーム再生。
ちゃんと10個Insntanceが作られた。(InActive)
2017-02-26 23.55.05.jpg

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が用意される。

2017-02-27 00.04.04.jpg

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
            )
        );
    }
}

5
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
7