謝罪
2秒ではできません、ごめんなさい。
オブジェクトプールしたい
弾幕ゲーで弾Instantiateしてたら大変なことになったので、オブジェクトプールしたくなった。
簡単なオブジェクトプールくらいなら自分で書いてもそんなに時間はかからない気がするが、書きたくないのでアセットに頼りたい。
Lean Pool を使って楽しよう
使いかた
ダウンロードしてインポートする。
プールしたいオブジェクトのInstantiateとDestroyを置換する。
Instantiate(poolShitaiObject);
-> Lean.Pool.LeanPool.Spawn(poolShitaiObject);
Destroy(poolShitaiObject);
-> Lean.Pool.LeanPool.Despawn(poolShitaiObject);
これだけでプールされるが、もう少しやることはある。
初期化
同じオブジェクトを使いまわす以上、以下のような普段やってる初期化は当てにならない。
AwakeとStartが都度呼ばれないのだ。
class Ahan : MonoBehaviour {
public Ahahan ahahan;
// 何もしてないので、再利用されるとき、値が引き継がれてしまう。
public int ahanCount = 0;
public int ahanAhanCount;
private void Start() {
ahahan = GetComponent<Ahahan>();
// Startは一度は呼ばれるが、再利用時には呼び出されないので、値が引き継がれてしまう。
ahanAhanCount = 10;
}
private void Update() {
ahanCount++;
ahanAhanCount++;
}
}
変更される可能性のある値は全てOnEnableの中で初期化すべし。
class Ahan : MonoBehaviour {
public Ahahan ahahan;
public int ahanCount;
public int ahanAhanCount;
private void Start() {
// 変化しない値はStartのままでいい。
// 重たくない処理の場合は脳死で全部OnEnableにおいてもええで
ahahan = GetComponent<Ahahan>();
}
// Spawn時に毎回呼び出されるため、値がリセットされる。
private void OnEnable() {
ahanCount = 0;
ahanAhanCount = 10;
}
private void Update() {
ahanCount++;
ahanAhanCount++;
}
}
OnEnableはStartの完全な代替にはなれない
なぜならStartはInstantiateされた次のフレームに実行されるが、OnEnableはSpawnされた時点で実行されるからだ。
どういうことかというと、
Instantiate -> 変数にいろいろ代入 -> 次のフレームにStartが実行されて、代入された値をもとに準備ができる
がStartは出来るのに対して、OnEnableは、
Spawn -> OnEnableがその瞬間実行される -> 変数にいろいろ代入 -> OnEnableはもう実行済みのため、次のフレームでは実行されず、値が反映されない
という感じになる。
普通に使っている分には脳死でStart -> OnEnable
で問題ないはず。
プールサイズを設定する
ただInstantiateとDestroyを置き換えただけでも高速化はされる。
しかしプールサイズが設定されていないため、弾が増える最初のタイミングはやはり重い。
最初から使いまわす用のインスタンスを用意しておくと、このコストもなくなる。
プールオブジェクトを作る。
Prefabのところに弾のPrefabを置いて、Preloadに用意したい弾の数を入れる(適当に1000)。
比較してみる
これで君もニッコリ
やったね!