Unity 新しいPrefab システム

Unity 2018.3 で導入予定の新しいPrefab システムが試せる、
Preview版が公開されました。

unity3d.com

このサイトにアクセスして、"Get the preview build"のリンクからダウンロードできます。

上記サイトの最下部にドキュメントへのリンクがあります。

Unite Berline 2018 Keynote
New Prefab workflow のくだりは1h39m40sあたりから。
ハッピーな雰囲気に包まれている・・
youtu.be

従来のPrefab

簡単に従来のPrefabの作り方をおさらい。
Prefabを作るには、Hierarchyに配置したゲームオブジェクトをProjectビューにドラッグ。
(むかーし、先にAsset -> Create -> Prefab で作って置いてからドラッグするという時代もありましたが。)
作られたPrefabは、Hierarchyにドラッグする、またはSceneビューにドラッグすることでシーンに配置できます。

f:id:kurihara-n:20180623023018p:plain

Prefab_Cubeという、キューブゲームオブジェクトから作ったPrefabを3つシーンに配置した状態です。
配置されたゲームオブジェクトはPrefabを基にしているため、
Prefabに変更を加えると、同じように変更が適用されます。

f:id:kurihara-n:20180623105801p:plain

ProjectウィンドウのPrefab_Cubeのxスケールを2に変えた状態です。

Nested では無い、とは

新しいPrefab workflowの最も注目される機能がNested Prefabです。
これはPrefabの中に、さらに別のPrefabの参照を持たせられるということです。
では今まではどうだったのでしょうか。

f:id:kurihara-n:20180623115956p:plain
Prefab_Sphereという、スフィアゲームオブジェクトから作ったPrefabを用意して、シーンに配置しています。
一つはPrefab_Cubeの子として配置しています。
この状態でPrefab_CubeのインスペクタにあるApplyをクリックすると、
Prefab_Cubeは、Prefab_Sphereオブジェクトを子に持っているゲームオブジェクトという状態でPrefabに反映されます。

f:id:kurihara-n:20180623123537p:plain

その状態で、Prefab_Sphereのxスケールを変更してみた状態。
Prefab_Sphereをそのまま配置したゲームオブジェクトは、スケールの変更が反映されています。
Prefab_Cubeの子になっているものについては、スケールの変更が反映されていません。

このようにPrefabを基にしたゲームオブジェクトも、
別のPrefabの中に含んでしまうと、最初のPrefabとの関係性が無くなってしまいます。
最初のPrefabをPrefabとして独立して機能させたまま、他のオブジェクトに持たせたい場合、
スクリプトから生成するなどの必要がありました。
また、それではエディタ上で実行していない状態で見れないなど、不便がありました。

新しいPrefab

新しいPrefab workflowの紹介動画。
Improved Prefab Workflow
www.youtube.com

3つの要素として挙げられているのが、

  • Prefab モード
  • Nested Prefabs
  • Variants

になります。

ドキュメントは正式なものが整備されたので、こちらを参考にしてください。
https://docs.unity3d.com/Manual/Prefabs.html
(注 こちらは古いものとなります)先のサイト下部にあるリンクから見れるドキュメント。
docs.google.com
これを見ていきます。

以下、流れはドキュメントに従ってますが、画像などは独自のもので、細かいとこまでは合わせてません。(がっつり翻訳したものというわけではないので、細かいところはドキュメントを見ていただくのが良いかと思います)

Prefabの生成

Prefabの作り方は従来と同様で、ゲームオブジェクトをProjectビューにドラッグするとPrefabとなります。
PrefabをHierarchyやシーンビューにドラッグするとPrefabのインスタンスが配置されます。
Asset > Create > Prefab のメニューは無くなっており、お役御免となったようですね。

f:id:kurihara-n:20180624124147p:plain

Hierarchyでのゲームオブジェクトの表示が変わっており、アイコンが表示されるようになっています。
プレハブの場合は、青いキューブのアイコンになっています。また、これは従来通りにゲームオブジェクト名が青い文字になります。
また、右側に矢印がついており、これは次のPrefabモードに入るためのものになっています。

Prefabモードでの編集

Prefabモードでは、それまでのシーンとは独立したPrefabのオブジェクトだけに注目した状態でPrefabを編集することができます。
Prefabに対する編集は、全てのPrefabインスタンスに変更が反映されます。

Prefabモードへの入り方、出方

Prefabモードへ入るには、ProjectビューのPrefabをダブルクリックするか、HierarchyのPrefabの右に表示されている矢印をクリックします。

f:id:kurihara-n:20180624142154p:plain

Prefab モードに入ったところ。
一つのPrefabに注視して編集できます。

Nested Prefabの場合、Prefabの持っているPrefabを注視した状態に更に入ることができます。
その場合、上部の表示が階層を表したものになります。

f:id:kurihara-n:20180624170147p:plain

上の、Prefab_A | Prefab_B というのが、Prefab_AのPrefabモードのから、更にPrefab_Bに入った状態です。
階層に表示されているPrefabをクリックすると、そのPrefabを編集するモードにジャンプします。
また、Hierarchy上に左向きの矢印が表示されているので、
それをクリックすると一つ上のPrefabの編集モードに移動します。
一番、上の階層の場合、通常のシーンビューに戻ります。
また、Scenesと表示されている部分をクリックしてもシーンビューに戻ります。

自動セーブ

f:id:kurihara-n:20180624171420p:plain

Prefabモード、右上のAuto Saveチェックが入っている場合、Prefabへの変更が自動的にセーブされます。
このチェックはデフォルトでオンになっています。

f:id:kurihara-n:20180624171723p:plain

チェックを外すと、任意のタイミングでセーブすることができるボタンが表示されます。
また、チェックを外し、Prefabへの変更がある状態でPrefabモードを抜けようとすると警告が表示されてくれて、
セーブするか、変更を破棄するか選択することができます。

Editing Environment

Prefabモードは空っぽのシーンになりますが、設定することで背景用のシーンを設定することができます。
‘Edit > Project Settings > Editor’ からエディタ設定に入り、
‘Prefab Editing Environment’のところにシーンの設定フィールドがあります。

Regular Environment は通常のPrefabで、UI Environment はUI関連のPrefabの背景として使用されます。

f:id:kurihara-n:20180624204635p:plain

ライトを配置したシーンをenvironmentにした場合。

Instance overrides

Prefabインスタンスには以下の変更が行えます。

Prefabに含まれているGameObjectの親の付け替え、削除は出来ないので
Prefabモードで編集するようにとの警告が表示されます。

f:id:kurihara-n:20180624210710p:plain

インスタンスで変更したプロパティはプロパティ名が太字になってInspectorの左側に青いラインが表示されます。
また追加されたコンポーネントは、コンポーネント全体の左側が青いラインになります。

f:id:kurihara-n:20180624211324p:plain

この場合、Box ColliderのSizeが変更のあったプロパティ、
Event Triggerが追加されたコンポーネントになります。

また、Prefabインスタンスの子として追加されたGameObjectには
Hierarchyでプラスマークがアイコンに表示されます。

f:id:kurihara-n:20180624212113p:plain

このPrefab_Cubeの下にあるSphereが追加された場合の例でプラスが付いてます。

追加、変更が分かりやすくなったのはとてもいいですね。

Overrideが優先される

PrefabインスタンスでOverrideされたプロパティは、基のPrefabのプロパティより優先されて使用されます。
もし、基のPrefabのプロパティを変更したのに、意図したようにインスタンスに変更が反映されない場合、
Overrideされていないか確認して見ると良いでしょう。
また、そのような混乱をなるべく避けるために、Overrideの使用を本当に必要な場合に留めるというのも良いかもしれません。
とのことです。

アライメント

ドキュメントで alignmentと言われている、
Transformのpositionとrotation、RectTransformのposition,rotation,width,height,margins,anchors,pivotは、
インスタンスで変更され別の値が入るものとされているので、変更されてもPrefabからの変更とは見なされません。

インスタンスからのPrefab編集

f:id:kurihara-n:20180625010118p:plain

PrefabインスタンスのInspectorの上部には3つボタンがあります。
Open, Select, Override となります。
OpenはPrefabモードでPrefabを開きます。
SelectはProjectビューでPrefabをフォーカスします。
Overrideはドロップダウンメニューを開きます。

Overrides ドロップダウン

f:id:kurihara-n:20180625012714p:plain

変更のあるコンポーネントや、追加されたコンポーネントが全て表示されます。
Apply All で基のPrefabに対して変更を反映させるか、
Revert AllでインスタンスをPrefabの状態に戻すか、2つのボタンで操作が出来ます。
表示されているコンポーネントを選択すると、
さらに左側に表示が展開され、変更点の差分が表示されます。

コンテキストメニュー

コンテキストメニューからもApply/Revertの操作が出来ます。
コンテキストメニューはInspectorのコンポーネントごとの右上にあるギアのマークで開くメニューです。

f:id:kurihara-n:20180625020925p:plain

Prefabインスタンスから削除されたコンポーネントは、薄い表示をされるようになっていて、
コンポーネントメニューが開けるようになっています。
f:id:kurihara-n:20180625021211p:plain

Prefabインスタンスに子として追加されたGameObject(プラスマークが付いているもの)は右クリックメニューで
Apply/Revertが選択できます。

f:id:kurihara-n:20180625021523p:plain

Nested Prefabs

注目の、大きな変更点、Nested Prefab。
Prefabのインスタンスが、基のPrefabへのリンクを持ったまま、別のPrefabに含まれるようになりました。

Prefabモードでの追加

通常のシーンでやるように、
Prefabモードで、ProjectビューからSceneビューまたはHierarchyにPrefabをドラッグすると追加できます。

f:id:kurihara-n:20180625023527p:plain

このようにPrefabモードのHierarchyツリーにも、青いキューブアイコンのPrefabが追加されています。

インスタンスからの追加

シーンに配置されているPrefabインスタンスに対して、子として別のPrefabインスタンスを加えると、他のゲームオブジェクト同様にプラスが付いた状態になります。
右クリックのメニュー > Added GameObject > Apply to 'Prefab Name' でapplyすることでもPrefabに追加できます。

ちょっとした補足ですが、
Nested Prefabが可能になったので
循環する参照だとどうなるかというのが気になったのですが、
例えばPrefab_AがPrefab_Bのインスタンスを持っており、
そのPrefab_Bに今度はPrefab_Aのインスタンスを持たせるような場合、
これが出来てしまうとツリー上で子が延々と続いてしまうことになりますが、
そういう操作をしようとした場合にはちゃんと警告が出てくれました。

f:id:kurihara-n:20180625024149p:plain

Prefab variants

これも新機能、Prefab variant。
Prefab variantsは、別のPrefabからプロパティを継承しているPrefabになります。
この機能がある背景として、Prefabが要素を変更した(Overrideされた)子のPrefabインスタンスを持つことが出来るのと同様に、
要素を上書きしたルートPrefabインスタンスを持つことが出来る、というところから来ているようです。

Prefab variantの作り方

ProjectビューでPrefabを右クリックし、Create > Prefab Variant とすることで同じパスに Prefab variant が作成されます。
この方法では、まだベースのPrefabから変更点のない状態で作成されるので、Prefabモードなどで変更を加えていくことになります。

シーンに配置されたPrefabインスタンスをProjectビューにドラッグすることでも作成することが出来ます。
Projectビューにドラッグすると、新規のPrefabを作るか、Prefab variantとして作るか選択するダイアログが表示されます。

f:id:kurihara-n:20180625035745p:plain

Prefab variantを選ぶと、ベースとなるPrefabを継承するPrefab variantとして作られ、
この場合、インスタンスに対してプロパティの変更があればOverrideとして変更点を持った状態で作成されます。

Prefab variantのアイコンは、分岐した矢印が書かれたブルーのキューブになっています。

f:id:kurihara-n:20180625040131p:plain

Prefab variantのエディット

Prefab variantのPrefabモードでの編集では、HierarchyのルートがベースPrefabのインスタンスとなっています。
(アイコンも、Prefabの青いキューブ)
f:id:kurihara-n:20180625040823p:plain

シーンでPrefabインスタンスにOverrideを加えるのと同じようになっています。
ベースPrefabが子として持っているGameObjectは削除できないですし、
加えた子のGameObjectはプラスが付いて、右クリックのメニューからApplyすることでベースPrefabにも反映させることができます。

f:id:kurihara-n:20180625041445p:plain

Overrideの変更点をApplyするということはベースPrefabに対しての操作になるため、
分かりやすさのために、Overridesメニューのボタンが'Apply All to Base'になっています。
f:id:kurihara-n:20180625042759p:plain

Prefab variantは変更点を持った状態をさらにPrefabに出来るので、
使い方によっては便利かもしれませんが、運用は少し注意がいるかなと思いました。

複数のレベルでのOverrides

Nested Prefabを持つPrefabインスタンスへの操作などで、どちらに対してApplyするか選択するケースがあります。
その場合、コンテキストメニューでApply対象が選択出来るようになります。

f:id:kurihara-n:20180625043758p:plain

ルートのPrefabインスタンスのOverrideとしてapplyするか、
もしくはNested Prefab自体へ変更をapplyするか、
下であればNested Prefab全体に変更が反映されることになります。

Prefabの展開(解除)

PrefabインスタンスをただのGameObjectとして扱いたい場合に、
右クリックから'Unpack Prefab'を選択することでGameObjectにできます。
Nested Prefabを中に持つようなPrefabだった場合には、それはPrefabインスタンスとして残ります。
そういった中に持つ全てのPrefabを解除したい場合は、'Unpack Prefab Completely'のほうで全てがただのGameObjectになります。

f:id:kurihara-n:20180625044928p:plain

従来のPrefabシステムでの'Break Prefab Instance'のようなものかと。


正式リリース時には機能変更があるかもしれないので、
ドキュメントなど公式のもの適宜見ていただくと良いかと思います。