Unity2018.3以降でPrefabを使う方法です。
Unity2018.3からPrefabワークフローが刷新されたことに伴ってまとめた内容となりますが、
Unity2018.2以前を使ったことがない方にもわかるように書いています。
- Prefabとは?
- Prefabを作る・インスタンス化する
- インスタンスは上書きできる(Instance Override)
- インスタンスで上書きできないもの
- HierarchyからPrefabを編集する(Overridesドロップダウンを使わない方法)
- HierarchyからPrefabを編集する(Overridesドロップダウンを使う方法)
- PrefabモードでPrefabを編集する
- Prefabを入れ子にできる(Nested Prefab)
- Prefabの変異体を作る(Prefab Variant)
- Prefabとの紐づけを解除する(Unpack)
- 参考
この記事はUnity2018.3.1f1を使って書いています。
Prefabとは?
PrefabとはGameObjectをテンプレートとして使う仕組みです。
たとえばいまモデルやスクリプトを色々使って敵キャラクターを作ったとします。
これを元にしたPrefabを作ります。
すると、このPrefabをテンプレートとして敵キャラを複製できます。
これをPrefabをインスタンス化するといいます。
Prefabはテンプレートなのでいくらでもインスタンス化して敵キャラを複製できます。
概要としてはこんな感じの機能です。
Prefabを作る・インスタンス化する
PrefabはHierarchyのGameObjectをProjectビューにドラッグ&ドロップするだけで作れます。
アイコンが青くなればPrefab化できています。
このPrefabをHierarchyにドラッグ&ドロップすればインスタンス化できます。
増えました。(ちょっと位置をずらしました)
Prefabに変更を加えるとこれらのインスタンスも変わります(やり方は後述します)。
インスタンスは上書きできる(Instance Override)
前節のようにインスタンスにはPrefabの変更が反映されますが、
下記の項目インスタンスごとに上書き(オーバーライド)することもできます。
オーバーライドするにはインスタンスのInspectorから普通に編集するだけです。
例えば前節のインスタンスのうち、片方のスケールだけオーバーライドして2倍にしてみます。
値をオーバーライドすると上図のように左側に青い線がつきます。
これがオーバーライドされている目印です。
オーバーライドしたものは元のPrefabの変更が反映されません。
例えばここまでの状態で元のPrefabのScale.yを2.5倍にしてみます。
オーバーライドした方には変更が反映されません。
このようにオーバーライドしすぎるとPrefabにしてテンプレート化している意味がなくなってくるので、
オーバーライドは最小限に抑えるのがUnity的におすすめとのことです。
ちなみに、コンポーネントの追加や削除をオーバーライドして行うと次のように表示されます。
GameObjectをオーバーライドで追加するとこのように+ボタンが表示されます。
インスタンスで上書きできないもの
インスタンスオーバーライドできないものもあります。
たとえば、階層構造はインスタンスで変更できません。
しようとするとインスタンスではなくPrefabを編集するように言われます。
またGameObjectの削除もできません(追加は前節の通りできます)。
PrefabにあるGameObjectをどうしても削除したい場合、非表示にすることはできます。
また、位置や回転など配置に関するプロパティはオーバーライドされません。
RectTransformの場合はこれに加えて幅、高さ、マージン、アンカー、ピボットがインスタンスごとに固有です。
HierarchyからPrefabを編集する(Overridesドロップダウンを使わない方法)
次に、一度作ったPrefabを編集することを考えます。
一つ目の方法はHierarchyで編集した内容をPrefabに反映する方法です。
まず、適当にインスタンスのScaleを変えて(オーバーライドして)みます。
オーバーライドしたプロパティを右クリックすると、Apply to Prefabという項目が出てきます。
Prefabのプロパティの値がこの値に書き換えられます。
ちなみにRevertはインスタンスでオーバーライドした値をPrefabの値に戻します。
一つのコンポーネントの変更を丸ごとPrefabに反映したい場合には、
コンポーネントのContext MenuからModified Component > Apply to Prefabを選択します。
コンポーネントの削除や追加もContext Menuから反映できます。
GameObjectの追加はHierarchyで右クリック > Added GameObject > Apply to Prefabで反映します。
HierarchyからPrefabを編集する(Overridesドロップダウンを使う方法)
このようなApply / Revert操作はインスタンスのRootのGameObjectのInspectorから
Overridesドロップダウンを開くことでも行えます。
開くとこんな感じのメニューが出てきて、変更を加えたものの一覧が出てきます。
これらを選択すると変更前と変更後の状態を比較することができます。
そして個別にApply / Revertができます。
また、すべての変更を反映したり戻したりする場合には、
Apply All / Revert Allを選択します。
PrefabモードでPrefabを編集する
前節のように、PrefabはHierarchyから変更をすることができますが、
Prefabモードを使えばPrefabを直接編集することもできます。
Prefabモードに入るには以下のいずれかの操作を行います。
操作 | 参考画像 |
---|---|
Prefabをダブルクリックする (Projectビューで) |
|
Hierarchyでインスタンスの右に 表示される矢印をクリックする |
|
ProjectからPrefabを選択しInspectorの Open Prefabをクリックする |
するとSceneビューに次のような画面が開かれてPrefabを編集できるようになります。
変更内容は右上のAutoSaveにチェックが入っていれば自動的に保存されます。
ただしPrefabが大きいとかでAutoSaveの処理が重くなって作業効率が悪いときにはこのチェックを外します。
チェックを外すとSaveボタンが現れるので、これを使って手動で保存します。
編集が終わったらSceneビュー上部のパンくずリストかHierarchy上部の矢印から元のSceneに戻れます。
ちなみにPrefabモードの環境(Scene)は下記の手順で変えることができます。
- Edit > Project Settings > Editor
- Prefab Editing EnvironmentのRegular / UI Environmentに環境として表示したいシーンを設定する
Prefabを入れ子にできる(Nested Prefab)
Prefabは入れ子にできます。
やり方としては、Prefabモードで普通に他のPrefabをドラッグ&ドロップするだけです。
また、インスタンス同士を入れ子にしてからApplyしても元のPrefab同士が入れ子になります。
少し複雑なのが、入れ子にしたときに子Prefabのプロパティを編集する場合です。
これは、親Prefabで子Prefabのプロパティをオーバーライドしている状態です。
すなわち、子Prefabには変更が加わっていません。
これをもし子Prefabにも反映させたい場合はApplyする必要があります。
子Prefabのプロパティをオーバーライドするのはかなり管理が煩雑になりそうですね…。
Prefabの変異体を作る(Prefab Variant)
Prefabバリアントという機能を使うとあるPrefabのプロパティだけを変えたPrefabを作れます。
具体的には大きさ違いのキャラとか色違いのキャラとかが作れます。
わかりづらいので試しにやってみましょう。
まずSphereを作ってPrefab化しておきます。
そしてこのPrefabのインスタンスをProjectビューにドラッグ&ドロップします。
すると新しくPrefabを作るのか、Prefab Variantを作るのか聞かれるので、Prefab Variantを選択します。
結果、このようなアイコンのPrefab Variantが生成されます。
またバリアントはPrefabを右クリック > Create > Prefab Variantからでも生成できます。
さてそれではバリアントを編集します。
編集方法は普通のPrefabと変わりません。
今回はMeshを変更してみました。
これでMeshだけが異なるPrefabの変異体が生成できました。
ちなみにバリアントに加えた変更を元のPrefabに反映したい場合には
インスタンスの変更の反映と同じように反映すればOKです。
Prefabとの紐づけを解除する(Unpack)
PrefabのインスタンスとPrefabとのつながりを解除するにはUnpackを行います。
Hierarchyからインスタンスを選んで右クリック > Unpack Prefabを選択します。
するとこれはPrefabのインスタンスではなくただのGameObjectになります。
Prefabとの紐づけが切れるだけなので、Prefab自体は消えません。
ここで一つ注意が必要なのが、Prefabを入れ子にしている場合です。
この状態で親をUnpackすると、親Prefabとの接続は切れるものの子Prefabとの接続は切れません。
完全に接続を切るには、Unpack Prefab Completedlyを選択します。
これですべてのPrefabとの接続が解除されました。