UnityのPrefabの扱いについて
UnityのPrefabはただの設定ファイルなのでリソースの一種
ただ管理できるデータが多すぎるがゆえに扱いが悩ましい。
例えば複数の敵を用意するとなった時に
スプライトとステータスを敵毎に用意する場合
敵毎にPrefabを用意し、スプライトやステータスを設定する事もできる。
シーン上で目で見て確認もできる。
Prefab Variantsを使えばPrefabの共通設定を1つにまとめて
異なる部分だけPrefab Variantsで設定もできる。
が、しかし
敵のステータスなどの情報はPrefabで設定したくない。
ちょっとミスってステータス変えてしまうというのも嫌だし
どちらかというとエクセルなど一覧の表で定義しjsonなどで吐き出したい
そうなるとPrefabはSpriteしか違いがなくなってしまい
Spriteを分けるためだけにPrefabを敵の数だけ用意するというのもいかがなものかとなってくる
敵のステータスデータに敵の種類やIDなど設定しておき
このIDならこのSpriteというデータがあるほうが管理しやすい。
ただこれをするとゲームを動かさないと動作が確認できず
Unityのゲームを起動しなくても見た目を調整したりできるという恩恵(弊害?)が消える
プログラムで制御する事と、Unity上で作りこむ
というのは結構相性が悪い
逆にあまり共通点がなく、それぞれ独立して作りこむような場合や
UIなど配置情報を多く含む場合はPrefabは有用なので
やはりこれも作るモノの性質によってどこまでPrefabでやるかを考えないといけない気がする
Prefabにあれこれ詰め込むのはNGという見解に至る。
例えばキャラクターのPrefabに、キャラとセットで使うからと何かしらアイコン的なPrefabを入れ子にする
といった作りはよくない。
キャラクターが100体いたとして、そのアイコンは同時に100個必要だろうか?
Prefabに含めてしまうと、いつか使うかもしれないというオブジェクトが無駄にメモリに乗ってしまう。
最終的にメモリを食うし、Instantiateも遅くなる。
そして開発終盤にならないとそのデメリットが顕著に表れないという罠がある。
ゲーム進行度によって表示されるオブジェクトが増えるようなケースだと
ゲームを進めるほど遅く、重くなるという問題につながるがそれになかなか気づけない。
それが分かった時には時すでに遅し
確かにPrefabに詰め込んでしまえば、開発する側は楽なところはあるかもしれないが
Prefabは基本シンプルに、キャラならキャラ、アイコンならアイコンと用意し
プログラマブルにそれらを組み合わせる方があとあとは幸せだろうと思う。
ちゃんとオブジェクトプールして、必要最低限で運用するのは徹底したいところ。
それだと開発しにくいという声もありそうだけど
ゲームのクオリティを下げて開発しやすい方を取るというのは本末転倒なので
その塩梅についてはプログラマ、非プログラマーがしっかり考えて扱わないと悲劇になると思いまする。
Prefabの用途として以下のケースは有用と考える。
- 座標やスケールなどロケーションに関する情報
- 3Dモデル、テクスチャ、マテリアルのセット
- UI
ロケーション
2D、3D問わず、画面上のどこにどんな大きさでという情報をプログラム内の定数で定義するのはあまりよい手法ではなく、実際にエディター上で配置した位置をそのままデータ化したいため、そのケースにおいてはPrefabは有用なリソースと思われる。
以下のようにルートオブジェクトに位置などを持つゲームオブジェクトを内包しておき、locationをPrefabにするという方法は便利だと感じる。
location
+ pos1
+ pos2
+ pos3
pos1などは基本はtransformのみを持ったシンプルなモノで、SpriteRendererなど見た目に関する情報は持たせていない、フィールド系は3Dモデルになると思うし、UI系はUIとしてまとめたい。
このPrefabはモデルでもUIでもないが配置情報を持ちたい時に使っている。
3Dモデル
3Dモデル、テクスチャ、マテリアルはだいたい1セットで1つのリソースと捉えて問題ないので、Prefabでまとめてしまう。
UI
UIに関しても配置やデザインがワンセットになっている方が都合がよい事が多いためPrefab管理が都合がいいケースが多いと思われる。
ただ共通で使用するテクスチャ、フォントなどが各々のPrefabに含まれて無駄なメモリを消費しないように注意しながら作成する必要はある。