【Unity】 低負荷で弾幕を処理/形成したい 【オブジェクトプール】

 Unityで弾幕を処理する方法になります。タイトルの通り"低負荷"でたくさんの弾を処理するために、オブジェクトプールして自作ゲームに実装しました。

Tags

インスタンス化 → Destroy は重い


 Unityで安直にPrefab(弾)をインスタンス化し、それを発射してDestroy()をするとどうなるでしょうか。

 同時に発射する弾が少なければ問題はありませんが、弾幕を張ろうものなら……はい、処理落ち地獄ですね!

 処理落ちの主な原因はインスタンス化(instantiate() )です。したがって、インスタンス化を事前にしておき、それを使いまわすという方法が王道です。

オブジェクトプール


 事前にオブジェクトを用意することをオブジェクトプールといいます。

 具体的には、Start()やAwake()関数でインスタンス化を行なっておき、あとはgameObject.SetActive()を駆使して使いまわすといったことをします。

 そのためには最低でも用意されたオブジェクトの中で非アクティブ状態のものを探すといった処理が必要です。

 まあ簡単で、用意したオブジェクトリスト/配列をforeachで回して一番最初の非アクティブのオブジェクトを返すだけです。

foreach(GameObject child in _poolObj){

  if(child.activeSelf == false){

    return child;

  }

}

 弾を非アクティブ状態にする処理は弾にアタッチしたスクリプトで処理すればいいと思います。

物理演算は重い


 当たり前ですが物理演算は重いです。弾幕に物理演算を使用する必要がなければRigidbidyはアタッチするべきではありません。アタッチするだけでPhysicsのループ処理が入ります。

 colliderだけでもRigidbodyがアタッチされたオブジェクトが相手ならば衝突判定がとれるので心配はありません。

 それに伴い、colliderのisTriggerにチェックすることをおすすめします。

実際にいっぱい弾を撃ってみる


 現在開発中のゲームの画面になります。そもそも今回の記事を作成したのは私自身が困っていたからなんですね~。

danmaku

ここまで読んでくださりありがとうございます。