Unityに関連する記事です

 Unityでは、シーン内に配置されたゲームオブジェクトが増えると、シーンの容量が増大し、パフォーマンスに悪影響を及ぼす可能性があります。

 そこで、効率的なシーン管理とリソース使用を実現するために、プレハブを活用してゲームオブジェクトを動的に生成する方法を学びましょう。



1.シーンでのオブジェクト管理


 ゲームシーンにはたくさんのゲームオブジェクトを配置できます。
それに伴い、シーンファイル(拡張子が .unity)の容量が肥大化していきます。
特に Github などを利用してバージョン管理を行っている場合、1つのファイルの容量が 100メガを超えるとプッシュが出来なくなります。

 そのため、シーン内に配置するゲームオブジェクトは、その容量の管理を行うことが最適化につながります。



 もっとも効果的な方法の1つには、ゲームオブジェクトのグループ化、およびグループ化したオブジェクトをまとめてプレハブ化することです。
オブジェクトの親子関係の活用と階層構造の設計を事前に行っておき、グループ分けを行います。

 1つ1つのゲームオブジェクトをプレハブにする方法ではなくて、グループとなるゲームオブジェクト群を作り、丸ごとプレハブにする方法です。

 このとき、グループを作ってからプレハブにしてしまうと、それぞれのグループの関連性がなくなってしまうため、
プレハブ・バリアントの機能を利用して作成するようにします。


2.親となるゲームオブジェクトの作成とプレハブ化


 オブジェクトのプレハブ化について説明します。

 ヒエラルキーにおいて「Create Empty」オブジェクトを作成して、それをグループの親オブジェクト(Group)とします。
名称はわかりやすく、「〜 Group」や、「Group_ 」のような形で、規則性を持つ名称にしておくとよいでしょう。

 続いて、この Group ゲームオブジェクト専用のクラスである GroupManager スクリプトを作成してアタッチし、プレハブにします。
スクリプトの内容については後述しますので、まずは GroupManager スクリプトを作成して、アタッチだけしてください。

 この手順により、子オブジェクト(グループ内)がない状態の Group プレハブが作成されます






 最初に親となるオブジェクトをプレハブにしている理由ですが、目的はプレハブのバリアント機能を利用するためです。

 プレハブは、さらに別のプレハブとして作成することができます。
そのとき、別のプレハブとして作成するか、元になっているプレハブの情報を利用したバリアントとして作成するか選択できます。

 親オブジェクトをプレハブ化しておくことで、Group プレハブを元にしたバリアントが作成できます。
バリアントの機能を利用すれば、グループ内の設定を一度に変更することができ、一貫性を保つことが容易になります。
また、バリアントごとに振る舞いを変えつつ、親オブジェクトにクラスなどを追加した場合にまとめて反映できます。

 Group ゲームオブジェクトをプレハブにすることで、これを利用して作られた他の Group をバリアントにして利用できます。


3.グループの作成とプレハブ・バリアントの作成


 オブジェクトのグループ化について説明します。

 まず、ヒエラルキーに、Group プレハブを配置します。
これはグループ分けする数だけ、個別に配置しますので、順番に作っていくとよいでしょう。

 つづてい、シーン内の関連するゲームオブジェクトをヒエラルキーより選択し、それらをすべて Group ゲームオブジェクトの子オブジェクトとします。
すでに親子関係があるゲームオブジェクトについては、それらをすべて、その構造のまま、Group ゲームオブジェクトの子オブジェクトにしてください。

 このようにすることで、親である Group ゲームオブジェクトをフォルダのように利用する形になり、
そのフォルダ内に、関連するゲームオブジェクトが入っている、という構造になります。

 グループ分けのポイントとしては、種類でまとめるのではなく、特定の地域や情報としてまとめておいた方がいいでしょう。
例えば、キャラクターのゲームオブジェクトが3体、建物のゲームオブジェクトも3つあったとき、キャラクターだけのグループを作るよりも、
キャラクターと建物とが、1つの地域として(村、街、森といった生息域)管理されているのであれば、それをそのままグループとした方が管理しやすいです。



 各グループが完成したら、親オブジェクトをプレハブとして保存します。
事前に Prefabs フォルダや、Valiants フォルダを用意しておくとよいでしょう。

 プレハブ化すると、オリジナルのプレハブとして作成するか、バリアントとして作成するか選択肢が出ますので、
バリアントを選択してください。





 これで Group プレハブを元にした、新しく派生した Group バリアントが作成されました。
バリアントのプレハブは、アイコンも通常のプレハブとは異なります。





 上記の画像であれば、Group プレハブを元に、それから派生した Group_A、Group_B、Group_C がバリアントのプレハブとして作成されています。
この3つのバリアントは別々の子オブジェクトを管理しているグループですが、元は Group プレハブとして共通の情報を持っています。

 そのため、Group_A に対して行った影響は、Group_A にのみ反映されます。Group_B、Group_C も同様です。
またこれらによって、元の Group プレハブへの影響もありません。

 ですが、Group プレハブに対して行った設定は、すべてのバリアントのプレハブに反映されます。


 こちらの教材も学習しておくと理解が深まります。

   => プレハブとプレハブバリアント


4.専用スクリプトの作成


  親オブジェクト用に専用のスクリプトである GroupManager を作成して、アタッチしてあります。
これは、Group バリアントのプレハブをインスタンス化するためのクラスとして設定します。

 このクラスには特別な情報を持たせる必要はありませんが、例えば、名前を付けて管理することも出来ます。
string 型、あるいは enum でグループ名を登録しておいて設定できるように出来ます。

 また、プレハブの状態になると、シーンにあるクラスの情報は失われます。
そのため、GameManager などの情報が必要な場合には、初期設定用のメソッドを用意しておくことで
メソッドの引数を通じて必要な情報を取得することが出来ます。

 合わせて、グループ内の子オブジェクトにも必要な情報を提供できるようにも出来ます。



GroupManager.cs

<= クリックすると開きます。


 スクリプトを作成したら、それぞれのバリアントに対して設定を行ってみてください。
Group_A バリアントに設定した情報は、そのバリアントにのみ反映されていることが分かります。

 逆に、Group プレハブの設定を変えると、すべてのバリアントに反映されることが分かります。








5.動的なインスタンス化の手順


 シーン内のオブジェクトをグループ化してプレハブ・バリアントにしたことで、シーンの軽量化が出来ました。

 ただし、ゲームとして動かしていくためには、バリアントの生成が必要になります。

 この処理を、例えば GameManager クラスのような、ゲーム開始時に実行するメソッドを持つ管理者役のクラスを使って
すべてのグループの生成を行っていく方法が考えられます。

 最初にすべてのグループを生成してもよいですが、Instantiate メソッド自体も負荷の高い処理の1つですので
適切なタイミングで、順次グループを生成していく方法が理想的です。

 例えば、特定のエリアの情報が解禁されたタイミングで生成する、処理の負荷が少ないタイミングで生成して隠しておく、といった方法があります。

 オブジェクトの頻繁な生成と削除はパフォーマンスに影響を与えることがありますので、最適化のためのよい設計を考えてみましょう。



 それではサンプルコードを提示します。

 ここでは GameManager クラスを作成し、その中で各グループのバリアントを登録して生成しています。


<= クリックすると開きます。


 groupPrefabs配列には、Inspectorから複数のバリアントのプレハブを設定できるようになっています。
for文を使って配列の順番に複数のGroupManagerを効率的に処理できるようになりました。

 ただし、最初にたくさん生成してしまうとパフォーマンスの低下がある場合には、for 文での生成は止めたり、
必要最低限のグループ数だけ生成するように調整してください。

 また、このサンプルではメンバ変数にはバリアントの情報だけを登録するようにしています。
生成した GroupManager を保持していませんが、必要に応じてメンバ変数を追加して代入しておくとよいでしょう。


ゲームを実行して挙動を確認する


 GameManager クラスを適宜なゲームオブジェクトにアタッチし(Create Empty しても構いません)、
配列にバリアントのプレハブを登録します。




 
 ゲームを実行して、グループ分けしたバリアントのプレハブが生成されるか、確認を行いましょう。



 これでシーンの軽量化と効率化を行うことが出来ました。

 次は、生成したグループが、ヒエラルキーにあるゲームオブジェクトとの繋がりを持ちたい場合の実装例です。

  => 効率的なシーン管理の手法例

コメントをかく


「http://」を含む投稿は禁止されています。

利用規約をご確認のうえご記入下さい

Menu



技術/知識(実装例)

2Dおはじきゲーム(発展編)

2D強制横スクロールアクション(発展編)

3Dダイビングアクション(発展編)

2Dタップシューティング(拡張編)

レースゲーム(抜粋)

2D放置ゲーム(発展編)

3Dレールガンシューティング(応用編)

3D脱出ゲーム(抜粋)

2Dリアルタイムストラテジー

2Dトップビューアドベンチャー(宴アセット使用)

3Dタップアクション(NavMeshAgent 使用)

2Dトップビューアクション(カエルの為に〜、ボコスカウォーズ風)

VideoPlayer イベント連動の実装例

VideoPlayer リスト内からムービー再生の実装例(発展)

AR 画像付きオブジェクト生成の実装例

AR リスト内から生成の実装例(発展)

private



このサイト内の作品はユニティちゃんライセンス条項の元に提供されています。

管理人/副管理人のみ編集できます