【Unity】Unityでプールデザインパターンを当てはめてみる

Unityでは、オブジェクトの再利用とパフォーマンスの最適化のために、プールパターン(Object Pooling)がよく使用されます。プールパターンは、頻繁に作成および破棄されるオブジェクトを事前に作成し、必要な時にそれらを再利用する方法です。

プールパターンの基本的な手順は以下の通りです。

  1. プールするオブジェクトの作成: 最初に、一定数のオブジェクトをプールに作成します。これらのオブジェクトは通常、同じプレハブを使用して作成されます。
  2. オブジェクトの有効化と非表示: ゲームの初期化時などに、作成したオブジェクトを非表示にしてプールに格納します。非表示にすることで、オブジェクトはシーン内で見えなくなり、処理負荷を軽減できます。
  3. オブジェクトの再利用: ゲーム中でオブジェクトが必要になった場合、プールから未使用のオブジェクトを取得し、必要な処理を行います。オブジェクトが再利用されるため、新たにオブジェクトを作成する必要がなくなり、パフォーマンスが向上します。
  4. オブジェクトの無効化と表示: ゲームでオブジェクトが使用されなくなった場合、再び非表示にし、プールに戻します。これにより、オブジェクトが再びプール内で使用可能になります。

プールパターンは、例えば弾丸やエフェクトのような頻繁に生成・破棄されるオブジェクトを効率的に処理するために使用されます。これにより、オブジェクトの生成と破棄に伴うオーバーヘッドを削減し、スムーズなゲームプレイを実現することができます。

Unityには、オブジェクトプールを実装するためのさまざまな方法があります。自作のプールシステムを作成することもできますが、Asset Storeなどから入手可能なプール専用のアセットを使用することもできます。また、C#の機能を活用して独自のプールクラスを作成することもできます。具体的な実装方法については、Unityのドキュメントやチュートリアルを参考にしてください。

サンプル

using System.Collections.Generic;
using UnityEngine;

public class ObjectPool : MonoBehaviour
{
    public GameObject prefab;  // プールするオブジェクトのプレハブ
    public int poolSize;  // プールするオブジェクトの数

    private List<GameObject> objectPool;  // オブジェクトのプール

    private void Start()
    {
        // オブジェクトのプールを作成
        objectPool = new List<GameObject>();

        // 指定した数のオブジェクトをプールに追加
        for (int i = 0; i < poolSize; i++)
        {
            GameObject obj = Instantiate(prefab);
            obj.SetActive(false);
            objectPool.Add(obj);
        }
    }

    // プールから未使用のオブジェクトを取得
    public GameObject GetObjectFromPool()
    {
        // プール内の非アクティブなオブジェクトを検索して返す
        for (int i = 0; i < objectPool.Count; i++)
        {
            if (!objectPool[i].activeInHierarchy)
            {
                return objectPool[i];
            }
        }

        // プール内に未使用のオブジェクトがない場合は新たに作成して返す(オプション)
        GameObject newObj = Instantiate(prefab);
        objectPool.Add(newObj);
        return newObj;
    }

    // オブジェクトをプールに戻す
    public void ReturnObjectToPool(GameObject obj)
    {
        obj.SetActive(false);
    }
}

上記のコードでは、ObjectPoolクラスがオブジェクトプールを管理します。prefab変数にはプールするオブジェクトのプレハブを設定し、poolSize変数にはプールするオブジェクトの数を指定します。

Startメソッドでは、指定した数のオブジェクトを作成し、非表示にしてプールに追加します。

GetObjectFromPoolメソッドでは、プールから未使用のオブジェクトを取得します。プール内の非アクティブなオブジェクトを探し、見つかった場合はそれを返します。プール内に未使用のオブジェクトがない場合は、オプションとして新たにオブジェクトを作成して返すこともできます。

ReturnObjectToPoolメソッドでは、オブジェクトをプールに戻します。オブジェクトを非表示にすることで、再利用可能な状態に戻します。

このサンプルコードを使用すると、以下のようにオブジェクトプールを利用できます。

public class ExampleUsage : MonoBehaviour
{
    public ObjectPool objectPool;

    private void Update()
    {
        // キー入力などのタイミングでオブジェクトをプールから取得
        if (Input.GetKeyDown(KeyCode.Space))
        {
            GameObject obj = objectPool.GetObjectFromPool();
            obj.SetActive(true);
            // オブジェクトの位置や挙動を設定
            obj.transform.position = Vector3.zero;
            obj.GetComponent<Rigidbody>().velocity = Vector3.up;
        }
    }
}

ExampleUsageクラスでは、ObjectPoolクラスを参照し、キー入力に応じてオブジェクトをプールから取得します。取得したオブジェクトはアクティブにし、位置や挙動を設定します。

注意点として、オブジェクトプールを使用する際には、オブジェクトがアクティブになったままになっていないか、プールに戻す際に必要な初期化を行っているかを確認することが重要です。

C#

Posted by hidepon