個人的勉強メモ置き場

プログラミングど素人のメモ置き場

オブジェクトプールを使ってちょっぴり負荷を軽減させる

オブジェクトプールってなんぞ

一時的なオブジェクトにオブジェクトプールを使うと、オブジェクトを作成し破棄するよりも時間がかかりません。なぜなら、メモリ割り当てが簡易になり動的メモリの割り当てのオーバーヘッドとガベージコレクション作業を削減できるからです。
スクリプトの最適化 - Unity マニュアル

毎回オブジェクトをInsantiateで生成して不要になったらDestoryとすると、特にシューティングゲームのようなものだと処理が重くなりがち。じゃあ破棄するんじゃなくて一旦SetActive(false)にして保管して使いまわそうというものらしい

こんな感じにしたい

f:id:zykb:20210119193055g:plain

あらかじめいくつかBulletを生成して、必要になったらSetActive(true)にしています。Bulletが画面外に出たらSetActive(false)で再利用。

作るにあたってこちらの記事を参考にさせていただきました。
megumisoft.hatenablog.com

Bullet.cs
public class Bullet : MonoBehaviour
{
    void Update()
    {
        // 移動処理
    }

    private void OnBecameInvisible()
    {
        gameObject.SetActive(false);
    }
}


OnBecameInvisible()はカメラの画面外に出たら一度だけ呼ばれるメソッドです。ここでSetActive(false)しています。
ちなみにOnBecameInvisibleはGameViewだけでなくSceneViewの表示範囲にも映ってると呼ばれないのでデバック時には注意

PlayerShoot.cs
public class PlayerShoot : MonoBehaviour
{
    [SerializeField]
    private GameObject bulletPrefab;
    [SerializeField]
    private Transform instPos;
    private List<GameObject> list_Bullets = new List<GameObject>();
    const int MAX_COUNT = 10;


    void Start() 
    {
        GameObject bullet;
        // あらかじめプールしておく
        for(int i = 0; i < MAX_COUNT; i++)
        {
            bullet = Instantiate(bulletPrefab);
            bullet.transform.parent = this.transform;
            bullet.gameObject.SetActive(false);
            list_Bullets.Add(bullet);
        }
    }

    void Update()
    {
        if(Input.GetMouseButtonDown(0))
        {
            BulletShoot();
        }

    }
    void BulletShoot()
    {
        for(int i = 0; i < list_Bullets.Count; i++)
        {
            if(!list_Bullets[i].gameObject.activeSelf)
            {
                list_Bullets[i].SetActive(true);
                list_Bullets[i].transform.position = instPos.position;
                return;
            }
        }
    }
}


start()内であらかじめ生成しておき、SetActive(true)にして射出位置に移動させています。


f:id:zykb:20210119193055g:plain

ヒエラルキーのBulletがオンオフになってるのがわかります。今回のようなゲームではさほど恩恵は無さそうですが、弾幕があるシューティングゲームではほぼ必須の要素なので積極的に使って行きたいですね。