デコシノニッキ

ホロレンジャーの戦いの記録

MRTKのObjectPoolを触る

ObjectPool

MRTKのUtilitiesにはちょいちょい便利なものが入っており,ObjectPoolもその一つです。
UnityのObjectPool関連資料はけっこうヒットするので,説明はそちらにお任せします。

doruby.jp

この3つのクラスが重要になります。

  • GameObjectPool.cs
  • GameObjectCreator.cs
  • IGameObjectListener.cs

使い方

GameObjectCreatorを継承してクラスをつくる

AbstractクラスであるGameObjectCreatorを継承して生成ロジックを書きます。
今回,Cubeを生成するCubeCreatorを作りました。

/// <summary>
/// GameObjectCreatorを継承して生成のロジックを書く
/// </summary>
    public class CubeCreator : GameObjectCreator
    {
        public override GameObject Instantiate()
        {
            return GameObject.CreatePrimitive(PrimitiveType.Cube);
        }
}

GameObjectPoolを作る

pool生成し,先ほど作ったCubeCreatorを識別子つきで登録します。

    /// <summary>
    /// Poolを生成する
    /// </summary>
    var pool = new GameObjectPool();

    //Poolに生成を担うクラスを識別子つきで登録する
    pool.AddCreator(new CubeCreator(), "Cube");

GameObjectを生成する

使う時は,識別子を指定してGameObjectを取り出します。Poolにオブジェクトがもう残っていなければ,新規にオブジェクトを生成します。

    pool.GetGameObject("Cube", Vector3.one, Quaternion.identity);

これを呼び出すたびにCubeが生成されます。

使い終わったGameObjectをPoolに保存する

オブジェクトプールに使い終わったGameObjectをRecycleで保存します。Destroyではなくfalseになるだけです。

    //生成する
    var cube = pool.GetGameObject("Cube", Vector3.one, Quaternion.identity);

    //使い終わったら識別子を指定して,ObjectPoolに保存
    pool.Recycle(cube, "Cube");

再度GetGameObjectで取り寄せようとすれば,enabled = falseになっているものから取り出してactiveにしていきます。足りなくなったら再度生成します。

    var cube = pool.GetGameObject("Cube", Vector3.one, Quaternion.identity);

大まかな使い方は以上です。

もう少し掘り下げます。
Abstract class である,GameObjectCreatorの中身です。今回は生成処理の Instantiate() だけを触りましたが,Poolから取り出すときにはPrepareForUseが,返す時はPrepareForRecycleと,それぞれで処理が走っています。

public abstract GameObject Instantiate();

public virtual void PrepareForRecycle(GameObject obj)
{
    var components = obj.GetComponents<MonoBehaviour>();
    foreach (var component in components)
    {
        if (component is IGameObjectCreatorListener)
        {
            (component as IGameObjectCreatorListene).PrepareForRecycle();
        }
    }
}

public virtual void PrepareForUse(GameObject obj)
{
    var components = obj.GetComponents<MonoBehaviour>();
    foreach (var component in components)
    {
        if (component is IGameObjectCreatorListener)
        {
            (component as IGameObjectCreatorListene).PrepareForUse();
        }
    }
}

Recycle,Useをする対象のオブジェクトが,IGameObjectListenerを実装したコンポーネントがアタッチされていれば,active, deactive 前に処理を呼び出してくれるようになっています。

また,今回GameObjectCreatorを継承してわざわざクラスを作りましたが,基本生成するオブジェクトを指定するというのは変わらないため,GenericPrefabInstanceCreatorという予めメンバにPrefabを指定できるクラスも用意されており,こんな感じに書けます。凝ったことをしたい訳でなければ基本,Genericで事足りると思います。

pool.AddCreator(
    new GenericPrefabInstanceCreator() {
        Prefab = prefab //生成してほしいPrefab
    }, "Cube");

[デコシノニッキ]は、Amazon.co.jpを宣伝しリンクすることによってサイトが紹介料を獲得できる手段を提供することを目的に設定されたアフィリエイト宣伝プログラムである、Amazonアソシエイト・プログラムの参加者です。」