2012年9月10日月曜日

Unity オブジェクトプールの作成 ~その1

ゲームの中でオブジェクトをどんどんインスタンス生成、破棄するとシーンによってはパフォーマンスに悪影響が出てくる。

そうしたときにどうすれば良いのだろうか?

ひとつの解決策がオブジェクトプールの作成だ。Unity Answersから翻訳を紹介する:


http://answers.unity3d.com/questions/7877/how-do-you-use-a-pool-of-objects-rather-than-creat.html

Nov 18, 2009

質問
オブジェクトの作成、破棄を繰り返すのでなくオブジェクトのプールを使用するにはどうしたら良いか?

ゲームプレイの際にインスタンス生成、破棄をするのでなく、再利用可能なオブジェクトのプール(弾丸、敵、爆発、その他)を作成、取得をするためにはどうしたら良いか?
フォーラムのレスのなかでStartのときにオブジェクトのプール作成して必要なときに取得するのが良いというコメントをみているが、実際に完成したスクリプトやシーンでのセットアップ例や実際にどうしたら良いかみたことがない。

回答
自分の作ろうとしてるゲームについてどこまで理解しているかがポイント。理解が深いほど最適化が可能だね。たとえば弾丸が必要で、ゲームのなかで弾丸1000個が1画面に出現する上限と分かっている場合を想定しよう。配列の中から次の弾丸を選ぶクラスは次のようなものだ:
※9/10 23:23 スクリプトの"<bullets.Length"以下が正しく表示されていなかったため修正

public class BulletGetter : MonoBehaviour {

    GameObject[] bullets;
    int lastBullet = -1;
    int bulletCache = 1000;

    void Awake(){
     bullets = new GameObject[bulletCache];
        for(int i=0; i < bullets.Length; i++){
            bullets[i] = new GameObject ("Bullet-"+i);
        }   
    }

    int GetNextBullet(){
        lastBullet +=1;
        if(lastBullet > bulletCache-1){
            lastBullet = 0;//reset the loop
        }
        return lastBullet;
    }
}
さらに様々な改善を加えることが可能。たとえば弾丸を使用中にアクティブ、非アクティブにする、画面に1000以上の弾丸が必要となった場合に自動的に配列の大きさを増やす、等々。あとはゲームオブジェクト作成の代わりにプレハブをAwakeでインスタンス化することもできる。

キャッシングのシステム上もっとも重要なことは、未使用になった場合に元に戻すメソッドを用意すること。もうオブジェクトを単純に破棄、作成することはないのだから、オブジェクトの状態を簡単に取得して変更できるようにスクリプトを工夫する必要がある。
-------

今回はコーディングでオブジェクトプール作成する方法をみてきた。

当然に自分でコーディングをしたほうが最適化できるのは明らかだろう。しかしUnityはコーディングやそのテストの時間がとれない人のための手段も用意している。そう、それがAsset Storeだ。

次回はAsset Storeからオブジェクトプールの作成に対応しているAssetを紹介する。

オブジェクトプールでパフォーマンスを改善するぞ ! Unity!

0 件のコメント:

コメントを投稿

ブックマークに追加

このエントリーをはてなブックマークに追加

自己紹介

自分の写真
Unity3D公式マニュアル翻訳やってる人がスマホ(iPhone, Android)のゲーム開発しています。気軽に面白く初心者が遊べる内容がモットー。Blogでは開発情報をひたすら、Twitterではゲーム作成の過程で参考にしている情報を中心につぶやきます

ページビューの合計

過去7日間の人気投稿

ブログ アーカイブ