LoginSignup
1
1

More than 3 years have passed since last update.

[Unity] UniRx の Object Pool を使わないで Object Pool してみる

Last updated at Posted at 2021-01-08

某所で 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ツール使えよという話。
ゴミですね。
供養(-人-)チーン

1
1
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
1
1