ObjectPool

Sukemitsuです

今回はUnityのゲームオブジェクトを複製して、繰り返し使うC#コードの共有です

シューティングゲームとかで弾を発射する場合、弾をゲームオブジェクトとして作ったり、壊したりを繰り返すと重くなりやすいのでそれに対応するものです

制作理由

Unity上で同じゲームオブジェクトを繰り返し使う際に利用できるコードです

SetActive()でゲームオブジェクトの有効化、無効化を切り替えて、

ゲームオブジェクト群をListで管理できます

割と汎用性が高くて使いやすいからクラス化、パッケージ化してコードを毎回書くのをやめたかっただけ

使い方

基本的な使い方は

1.SetSampleObject(GameObject)で複製したいゲームオブジェクトを登録

2.ゲームオブジェクトを使いたいときにGetObject()を呼び出すと複製されたゲームオブジェクトが返ってきます

この2ステップだけで使えます

あとは追加オプション的な関数がちょっとある程度です

使いそうなのはSetParent(GameObject)で複製するオブジェクト群の親となるオブジェクトを登録しておくと、UnityのInspecter上で複製されたオブジェクトが散らかることがないので楽です

以下コード

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/// <summary>
///  GameObject繰り返し利用クラス
/// </summary>
///

public class ObjectPool
{
    //複製するオブジェクト
    private GameObject _poolObj;

    //オブジェクトリスト
    private List<GameObject> _poolObjList;

    //親オブジェクト
    private GameObject _parentObj;

    //複製オブジェクト設定
    public void SetSampleObject(GameObject SampleObj)
    {
        //複製するオブジェクトの設定
        _poolObj = SampleObj;

        Debug.Log("SetSampleObject:_poolObj = " + SampleObj.name);
    }

    //親オブジェクト設定関数
    public void SetParent(GameObject parent)
    {
        //親オブジェウトの設定
        _parentObj = parent;

        Debug.Log("SetParent:_parentObj = " + parent.name);
    }

    //オブジェクトリスト生成関数
    public void CreatePool(int maxList)
    {
        //指定個数のオブジェクトを生成する
        for (int i = 1; i <= maxList; i++)
        {
            //複製
            var Obj = CreateNewObject();

            //非アクティブ化
            Obj.SetActive(false);
        }

        Debug.Log("ObjectPoolList Created! This List has " + maxList + "Objects!");
    }

    //未使用オブジェクトを見つけるか、新しくオブジェクトを作って返す関数
    public GameObject GetObject()
    {
        // 使用中でないものを探して返す
        foreach (var obj in _poolObjList)
        {
            //未使用オブジェクト発見
            if (obj.activeSelf == false)
            {
                //アクティブ化
                obj.SetActive(true);

                Debug.Log("Find " + obj.name + "!");

                //アクティブ化したオブジェクトを返す
                return obj;
            }
        }

        // 全て使用中だったら新しく作って返す
        var newObj = CreateNewObject();
        //アクティブ化
        newObj.SetActive(true);

        Debug.Log("All Objects are used! Create new Object:" + newObj.name);

        //新しく作ったオブジェクトを返す
        return newObj;
    }

    //新しくオブジェクトを作り、リストに追加する関数
    private GameObject CreateNewObject()
    {
        //オブジェクトを新しく作る
        var newObj = GameObject.Instantiate(_poolObj) as GameObject;

        //作ったオブジェクトの名前をつける
        newObj.name = _poolObj.name + (_poolObjList.Count + 1);

        //作ったオブジェクトをリストに加える
        _poolObjList.Add(newObj);

        //
        if (_parentObj != null)
        {
            //作ったオブジェクトのヒエラルキー変更
            newObj.transform.SetParent(_parentObj.transform, false);
        }

        //作ったオブジェクトを返す
        return newObj;
    }

    //List取得関数
    public List<GameObject> GetList()
    {
        return _poolObjList;
    }

    //オブジェクトpositionセット関数
    public void SetObjectPosition(GameObject Obj, Vector3 pos)
    {
        //位置調整
        Obj.transform.position = pos;
    }
}


参考サイト

【Unity】オブジェクトプーリングでオブジェクト節約術https://spirits.appirits.com/doruby/8907/?cn-reloaded=1

Sukemitsu

2021年度会計

2019年度加入生
投稿記事一覧

コメントを残す

CAPTCHA


新歓

前の記事

とあるRiG++部員の生態