【Unity】クソ雑に使えるオブジェクトプール

Unityでエフェクトやらを出すときってオブジェクトをプーリングすると思います。 Unity向けのオブジェクトプールの実装はいろいろありますが、雑に拾って雑に返せるものを用意して使ってます。

コード

クソ雑に使えるオブジェクトプール

つかいかた

プレハブを指定してインスタンスを取得します。 まだプールになければ中で実際にInstantiateされます。

var instance = GameObjectPool.Instantiate(original, position, rotation);

返すときはそのインスタンスを指定するだけです。

GameObjectPool.Destroy(instance);

プール自体の管理はいまのところ全削除だけ用意してます。 これはシーンのアンロード時にも勝手に呼ばれます。

GameObjectPool.ClearAll();

クソ雑ポイント

その1 : あらゆるGameObjectを突っ込める

既存のオブジェクトプール実装としてUniRxのObjectPool等がありますが、 これは対象のGameObjectが特定のコンポーネントを持っていることを前提としています。

専用のコンポーネントを持たない単純なエフェクトをプーリングしたい場合もあるのでそういう制約はナシにしました。

その2 : プールは世界に1つだけ

本当はその1つの中で複数持ってるんですが…使う側でそれを意識する必要ないよねという考えです。 また引き合いに出すと、UniRxのObjectPoolは管理したいオブジェクトの種類ごとにプールのインスタンスを持ってそれを制御する必要があります。

今回の実装では全てstaticなメソッドで制御する形にしてます。 プレハブを指定してインスタンスを取得。返すときはどのプールに返すべきかを知っている必要はありません。

例えば、こういうコンポーネントをエフェクトにくっつけておくと…

using UnityEngine;
using Cysharp.Threading.Tasks;
public class ReturnPoolInTime : MonoBehaviour
{
    [SerializeField]
    int ms;
    private async void Awake()
    {
        await UniTask.Delay(ms);
        GameObjectPool.Destroy(gameObject);
    }
}

指定したtimeだけ経過した後にプールに返す処理をエフェクトの種類によらず使い回すことができます。 この場合、生成する側はGameObjectPool.InstantiateしてほっとけばOKです。

おしまい

実は、これはプーリングなしで作っちゃってたゲームに後から導入するために作ったものです。 エフェクトのInstantiateやDestroyの前にGameObjectPool.だけくっつけとけばなんとなく動いてくれます。

同じくらいクソ雑にやりたければどうぞ。 正直、ちゃんと目的毎に別のプール作って管理できるならそのほうがいいかも…