【Unity】ObjectPool で花びらオブジェクトたちを管理する(中編)

前編では、「桜の花びら」ゲームオブジェクトたちを効率よく生成・破棄するため UnityObjectPool を利用する準備をしました。

ObjectPool のイメージ

中編では、ObjectPool に設定した 4 つの処理の説明をします。
※ Unity は 2021.3.14f1、 OS は Windows 10 です。

ObjectPool に設定した UnityEvent と Action

UnityEvent と Action はざっくり言えば関数自体を変数としてやりとりするときの型です。
ボタンが押されたときに呼びだす関数を指定する際などにも用いられます。

「xxxしたときには、この関数を呼び出してください」と ObjectPool に教えておきます。
そうすることで、オブジェクトを生成・削除するとき、オブジェクトを外部に渡す・外部から戻されるときなどのイベントで、教えられた関数を呼び出します。

ObjectPool<SakuraNoHanabira> を new するときにコンストラクタ引数で 4 つの関数を設定しました。
ここからは、その関数たちが呼び出されるタイミングと処理の内容について説明します。
※処理の最初にある Debug.Log は Console にメッセージを出力して、テストプレイ時にどのタイミングでどの関数が呼び出されているか確認するためのものです。

actionOnGet

「オブジェクトを下さい」と外部から ObjectPool が頼まれた際に、呼び出す Action です。
プールしているオブジェクトがあれば、外部に渡す前に、設定された関数を呼び出し、その中でオブジェクトに設定などをしたあとに、それを渡します。

            actionOnGet : (SakuraNoHanabira hanabira) =>
            {
                Debug.Log("actionOnGet Called." + hanabira.name);
                Vector3 pos = new Vector3();
                // 出現場所(固定)を設定します。
                pos.x = RespawnArea.x + Random.Range(0f, RespawnArea.width);
                pos.y = RespawnArea.y + Random.Range(0f, RespawnArea.height);
                pos.z = 0f;
                hanabira.transform.position = pos;
                // 有効にします。
                hanabira.gameObject.SetActive(true);
            },

引数は、プールされていたオブジェクトで、この処理の後で外部に渡すものです。
「桜の花びら」を出現させるときに使われるので、位置をランダムに決定し、オブジェクトが動作し表示されるようにアクティブにします。

createFunc

「オブジェクトをください」と言われたけど、手元に使っていないオブジェクトがない場合、新しくオブジェクトを生成するために、この関数を呼び出します。そのため戻り値はテンプレート引数の型が指定されていて、オブジェクトを返す必要があります。

            createFunc: () =>
            {
                Debug.Log("createFunc Called.");
                // Prefab のインスタンスを作成します。位置は actionOnGet で取得される直前にランダムに設定します。
                GameObject instance = Instantiate(Prefab, Vector3.zero, Quaternion.identity);
                return instance.GetComponent();
            },

以前に説明した Instantiate 関数によるプレハブインスタンスの生成を行い、それを戻り値として返しています。

actionOnRelease

「使い終わったのでこのオブジェクトをプールに戻します」と言われた際の対応です。

            actionOnRelease : (SakuraNoHanabira hanabira) =>
            {
                Debug.Log("actionOnRelease Called." + hanabira.name);
                hanabira.gameObject.SetActive(false);
            },

引数は外部から戻されたオブジェクトです。
actionOnGet の処理と対応させて、オブジェクトを動作せず表示もされない非アクティブにしています。

actionOnDestroy

オブジェクトを破棄するときに呼びされる関数です。

            actionOnDestroy : (SakuraNoHanabira hanabira) =>
            {
                Debug.Log("actionOnDestroy Called." + hanabira.name);
                GameObject.Destroy(hanabira.gameObject);
            },

createFunc に対応させ、 Instantiate したプレハブインスタンスを破棄する処理を行っています。

new で createFunc は呼び出されなかった

ObjectPool のコンストラクタ引数の defaultCapacity に 100 を指定したので、最初から 100 個のオブジェクトは作られるのかなと思っていました。
しかし、前述の Debug.Log 関数を使って、関数呼び出しを確認しようとしましたが、一度も呼び出されません。
次回紹介する ObjectPool の Get 関数を呼び出すと createFunc が呼び出されたので、必要に応じてオブジェクトを作り、戻されたオブジェクトを貯めておき、後でまた再利用する流れなのだと思いました。

続きます。たぶん次で一区切りになります。

コメント

Ads Blocker Image Powered by Code Help Pro

お願い - Ads Blocker Detected

このサイトは広告を掲載して運営しています。

ポップアップを閉じて閲覧できますが、よろしければ

このサイト内の広告を非表示にする拡張機能をオフにしていただけませんか?

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

We have detected that you are using extensions to block ads. Please support us by disabling these ads blocker.

タイトルとURLをコピーしました