【Unity】Unity2018.3以降におけるPrefabの使い方をちゃんと理解する

Unity2018.3以降でPrefabを使う方法です。

Unity2018.3からPrefabワークフローが刷新されたことに伴ってまとめた内容となりますが、
Unity2018.2以前を使ったことがない方にもわかるように書いています。

この記事はUnity2018.3.1f1を使って書いています。

Prefabとは?

PrefabとはGameObjectをテンプレートとして使う仕組みです。
たとえばいまモデルやスクリプトを色々使って敵キャラクターを作ったとします。

f:id:halya_11:20190112175957p:plain

これを元にしたPrefabを作ります。

f:id:halya_11:20190112180954p:plain

すると、このPrefabをテンプレートとして敵キャラを複製できます。
これをPrefabをインスタンス化するといいます。

f:id:halya_11:20190112181917p:plain

Prefabはテンプレートなのでいくらでもインスタンス化して敵キャラを複製できます。

f:id:halya_11:20190112181344p:plain

概要としてはこんな感じの機能です。

Prefabを作る・インスタンス化する

PrefabはHierarchyのGameObjectをProjectビューにドラッグ&ドロップするだけで作れます。

f:id:halya_11:20190112182308p:plain

アイコンが青くなればPrefab化できています。

f:id:halya_11:20190112182453p:plain

このPrefabをHierarchyにドラッグ&ドロップすればインスタンス化できます。

f:id:halya_11:20190112182810p:plain

増えました。(ちょっと位置をずらしました)

f:id:halya_11:20190112182851p:plain

Prefabに変更を加えるとこれらのインスタンスも変わります(やり方は後述します)。

f:id:halya_11:20190112183028p:plain

インスタンスは上書きできる(Instance Override)

前節のようにインスタンスにはPrefabの変更が反映されますが、
下記の項目インスタンスごとに上書き(オーバーライド)することもできます。

オーバーライドするにはインスタンスのInspectorから普通に編集するだけです。
例えば前節のインスタンスのうち、片方のスケールだけオーバーライドして2倍にしてみます。

f:id:halya_11:20190112184629p:plain

値をオーバーライドすると上図のように左側に青い線がつきます。
これがオーバーライドされている目印です。

オーバーライドしたものは元のPrefabの変更が反映されません。
例えばここまでの状態で元のPrefabのScale.yを2.5倍にしてみます。

f:id:halya_11:20190112185331p:plain

オーバーライドした方には変更が反映されません。

このようにオーバーライドしすぎるとPrefabにしてテンプレート化している意味がなくなってくるので、
オーバーライドは最小限に抑えるのがUnity的におすすめとのことです。

ちなみに、コンポーネントの追加や削除をオーバーライドして行うと次のように表示されます。

f:id:halya_11:20190112185856p:plain

GameObjectをオーバーライドで追加するとこのように+ボタンが表示されます。

f:id:halya_11:20190112190101p:plain

インスタンスで上書きできないもの

インスタンスオーバーライドできないものもあります。

たとえば、階層構造はインスタンスで変更できません。
しようとするとインスタンスではなくPrefabを編集するように言われます。

f:id:halya_11:20190112190945p:plain

またGameObjectの削除もできません(追加は前節の通りできます)。
PrefabにあるGameObjectをどうしても削除したい場合、非表示にすることはできます。

f:id:halya_11:20190112191237p:plain

また、位置や回転など配置に関するプロパティはオーバーライドされません。

f:id:halya_11:20190112191446p:plain

RectTransformの場合はこれに加えて幅、高さ、マージン、アンカー、ピボットがインスタンスごとに固有です。

f:id:halya_11:20190112191826p:plain

HierarchyからPrefabを編集する(Overridesドロップダウンを使わない方法)

次に、一度作ったPrefabを編集することを考えます。
一つ目の方法はHierarchyで編集した内容をPrefabに反映する方法です。

まず、適当にインスタンスのScaleを変えて(オーバーライドして)みます。

f:id:halya_11:20190112192414p:plain

オーバーライドしたプロパティを右クリックすると、Apply to Prefabという項目が出てきます。
Prefabのプロパティの値がこの値に書き換えられます。

f:id:halya_11:20190112192817p:plain

ちなみにRevertはインスタンスでオーバーライドした値をPrefabの値に戻します。

f:id:halya_11:20190112192932p:plain

一つのコンポーネントの変更を丸ごとPrefabに反映したい場合には、
コンポーネントのContext MenuからModified Component > Apply to Prefabを選択します。

f:id:halya_11:20190112193229p:plain

コンポーネントの削除や追加もContext Menuから反映できます。

f:id:halya_11:20190112193523p:plain

GameObjectの追加はHierarchyで右クリック > Added GameObject > Apply to Prefabで反映します。

f:id:halya_11:20190112193748p:plain

HierarchyからPrefabを編集する(Overridesドロップダウンを使う方法)

このようなApply / Revert操作はインスタンスのRootのGameObjectのInspectorから
Overridesドロップダウンを開くことでも行えます。

f:id:halya_11:20190112194958p:plain

開くとこんな感じのメニューが出てきて、変更を加えたものの一覧が出てきます。

f:id:halya_11:20190112195109p:plain

これらを選択すると変更前と変更後の状態を比較することができます。
そして個別にApply / Revertができます。

f:id:halya_11:20190112201440p:plain

また、すべての変更を反映したり戻したりする場合には、
Apply All / Revert Allを選択します。

f:id:halya_11:20190112201342p:plain

PrefabモードでPrefabを編集する

前節のように、PrefabはHierarchyから変更をすることができますが、
Prefabモードを使えばPrefabを直接編集することもできます。

Prefabモードに入るには以下のいずれかの操作を行います。

操作 参考画像
Prefabをダブルクリックする
(Projectビューで)
f:id:halya_11:20190112200836p:plain
Hierarchyでインスタンスの右に
表示される矢印をクリックする
f:id:halya_11:20190112200516p:plain
ProjectからPrefabを選択しInspectorの
Open Prefabをクリックする
f:id:halya_11:20190112200604p:plain

するとSceneビューに次のような画面が開かれてPrefabを編集できるようになります。

f:id:halya_11:20190112221406p:plain

変更内容は右上のAutoSaveにチェックが入っていれば自動的に保存されます。
ただしPrefabが大きいとかでAutoSaveの処理が重くなって作業効率が悪いときにはこのチェックを外します。
チェックを外すとSaveボタンが現れるので、これを使って手動で保存します。

f:id:halya_11:20190112221720p:plain

編集が終わったらSceneビュー上部のパンくずリストかHierarchy上部の矢印から元のSceneに戻れます。

f:id:halya_11:20190112221922p:plain

ちなみにPrefabモードの環境(Scene)は下記の手順で変えることができます。

  1. Edit > Project Settings > Editor
  2. Prefab Editing EnvironmentのRegular / UI Environmentに環境として表示したいシーンを設定する

f:id:halya_11:20190112222346p:plain

Prefabを入れ子にできる(Nested Prefab)

Prefabは入れ子にできます。
やり方としては、Prefabモードで普通に他のPrefabをドラッグ&ドロップするだけです。

f:id:halya_11:20190112222810p:plain

また、インスタンス同士を入れ子にしてからApplyしても元のPrefab同士が入れ子になります。

f:id:halya_11:20190112222934p:plain

少し複雑なのが、入れ子にしたときに子Prefabのプロパティを編集する場合です。

f:id:halya_11:20190112223232p:plain

これは、親Prefabで子Prefabのプロパティをオーバーライドしている状態です。
すなわち、子Prefabには変更が加わっていません。

これをもし子Prefabにも反映させたい場合はApplyする必要があります。

f:id:halya_11:20190112223454p:plain

子Prefabのプロパティをオーバーライドするのはかなり管理が煩雑になりそうですね…。

Prefabの変異体を作る(Prefab Variant)

Prefabバリアントという機能を使うとあるPrefabのプロパティだけを変えたPrefabを作れます。
具体的には大きさ違いのキャラとか色違いのキャラとかが作れます。

わかりづらいので試しにやってみましょう。
まずSphereを作ってPrefab化しておきます。

f:id:halya_11:20190112224233p:plain

そしてこのPrefabのインスタンスをProjectビューにドラッグ&ドロップします。

f:id:halya_11:20190112224500p:plain

すると新しくPrefabを作るのか、Prefab Variantを作るのか聞かれるので、Prefab Variantを選択します。

f:id:halya_11:20190112224719p:plain

結果、このようなアイコンのPrefab Variantが生成されます。

f:id:halya_11:20190112224809p:plain

またバリアントはPrefabを右クリック > Create > Prefab Variantからでも生成できます。

f:id:halya_11:20190112224900p:plain

さてそれではバリアントを編集します。
編集方法は普通のPrefabと変わりません。
今回はMeshを変更してみました。

f:id:halya_11:20190112225439p:plain

これでMeshだけが異なるPrefabの変異体が生成できました。

f:id:halya_11:20190112225538p:plain

ちなみにバリアントに加えた変更を元のPrefabに反映したい場合には
インスタンスの変更の反映と同じように反映すればOKです。

f:id:halya_11:20190112225810p:plain

Prefabとの紐づけを解除する(Unpack)

PrefabのインスタンスとPrefabとのつながりを解除するにはUnpackを行います。
Hierarchyからインスタンスを選んで右クリック > Unpack Prefabを選択します。

f:id:halya_11:20190112230106p:plain

するとこれはPrefabのインスタンスではなくただのGameObjectになります。
Prefabとの紐づけが切れるだけなので、Prefab自体は消えません。

f:id:halya_11:20190112230240p:plain

ここで一つ注意が必要なのが、Prefabを入れ子にしている場合です。

f:id:halya_11:20190112230353p:plain

この状態で親をUnpackすると、親Prefabとの接続は切れるものの子Prefabとの接続は切れません。

f:id:halya_11:20190112230526p:plain

完全に接続を切るには、Unpack Prefab Completedlyを選択します。

f:id:halya_11:20190112230454p:plain

これですべてのPrefabとの接続が解除されました。

f:id:halya_11:20190112230630p:plain

参考

docs.unity3d.com