Prefab Variants -Unity2018.3からのPrefab活用-

この記事は[Unity #3 Advent Calender 2018 19日目](https://qiita.com/advent-calendar/2018/unity3)の記事です。

ついに[Unity2018.3]((https://blogs.unity3d.com/jp/2018/12/13/introducing-unity-2018-3/))の正式リリースが発表されました。（2018年何とか滑り込ませてきましたね）
様々な性能面での改善は勿論のこと、今回のアップデートでは大幅な機能の追加もあり、待ち望んでいた方も多いではないでしょうか。

本記事では、そんなUnity2018.3から導入される新Prefabワークフローの一つであるPrefab Variantsの紹介と、その具体的な使用例を紹介しようと思います。

## Prefab Variants

Unity2018.3以降でUnityに入るPrefabに関する新機能で、一言で表すとPrefabの継承を可能にする機能です。
Prefab Variantsを用いることで、あるPrefabをベースとして、機能や構造、見た目にカスタムを加えたPrefabを作成できます。
勿論ベースとなるPrefabが変更されれば、それを継承するPrefab Variantsのベースとなる部分も更新されます。
同じような機能や構造、見た目を持つPrefabを量産する上でとても役に立つ機能です。

Variantという単語自体は変異体という意味で、Prefab Variantsという言葉はあるPrefabについて、それをベースにしつつも相違点のあるPrefabを指しています。
本記事でも、Prefab Variantsを用いた継承Prefabについて、Variantという呼称を用いて説明を進めていきます。

## 基本的な使い方

実際に簡単なPrefabを作りつつ使い方を説明していきたいと思います。今回は何かといろいろな場面に必要になるポップアップのUIパーツとなるPrefabを作っていきます。
<font color="Crimson">(なお本記事で操作しているUnityのバージョンは2018.3.0f2になります。バージョンの差異によっては操作や見た目に違いがある場合もあるのでご注意ください。)</font>

### 1: Variantの作成

まずはVariantのベースとなるPrefabを用意しましょう。適当なパネルとタイトルの文字だけを使用したシンプルなポップアップのベースを作ります。
BasePopUpというオブジェクトにポップアップの本体となるImageをアタッチし、子オブジェクトとしてタイトルとなるText、タイトル部分を判別するためだけのBarという矩形のImageをくっつけました。
これをBasePopUpという名前を付けてPrefabとして保存します。
![a1.PNG](https://qiita-image-store.s3.amazonaws.com/0/141004/5358881f-6d76-fcc1-08a0-38e9c210c55e.png)



早速このBasePopUpのPrefabについてVariantを作成します。
作成する手順は簡単で、ベースとなるPrefabの上で右クリックし、Create→PrefabVariantという項目を選ぶだけです。

![a2.PNG](https://qiita-image-store.s3.amazonaws.com/0/141004/1c333daa-074a-c99a-f393-fae2eaf603cc.png)

作成すると矢印の模様がついたアイコンのPrefabが作成されます、これがVariantです。
このVariantを使って簡単なメッセージを提示するポップアップを作ります。なので名前はMessagePopUpとしました。

![a3.PNG](https://qiita-image-store.s3.amazonaws.com/0/141004/81b791de-15c2-ddf1-2545-64f58d782080.png)

### 2: Variantの編集

Variantについても普通のPrefabと編集する方法は変わりません。Unity2018.3より導入された、Prefab Modeというゲームシーンとは隔離されたモードで行います。
編集したいPrefabを右クリックし、Openを選択するとPrefab Modeで選択しているPrefabの階層が開きます（今回のPrefabはuGUIなのでPrefab Modeの環境に自動的にCanvasが追加されます）。

<font color="Crimson">（このPrefab Modeの導入に伴い、従来のUnityのようなゲームシーン上でのPrefabの操作などは一部（削除や移動といったベース構造に影響をもたらす操作）は出来なくなっているので注意しましょう。）</font>

メッセージポップアップを作るので、適当なボタンとメッセージテキストを追加します。

![a4.PNG](https://qiita-image-store.s3.amazonaws.com/0/141004/f9c6e0ff-8715-90f2-832b-2a3914107726.png)

上図が実際に編集した画像になります。プラスマークが出ているのが追加した部分です。

右上にAuto Saveと書かれたチェックボックスがありますが、これは編集した際に即座に保存をするフラグになっており、これがオンになっていると従来のようなApplyを行う必要もなく編集が保存されます。Prefab Modeを終了する際にも特にこれといった操作も必要ありません。
逆にチェックボックスを外せば、明示的にSaveを行うことも可能ですし、Prefab Modeの終了時にSave確認の処理を走らせてくれます。

そしてVariantも通常のPrefabと同様に、Prefab Modeを終了してシーン上に配置すればいつものPrefabと同じようにインスタンスを生成して使用できます。

![a5.PNG](https://qiita-image-store.s3.amazonaws.com/0/141004/5c35f52d-84d4-b5c2-b265-6407503a104a.png)

従来のPrefabの保存操作であるインスペクタ-のApplyボタンはVariantへの変更についてのメニューのプルダウンメニューになっています。
上図のようなレイアウトになっており、Revert Allで変更を元に戻したり、Apply All to Baseボタンを押すことで、Variantの差分をベースのPrefabに反映させることもできます。

### 3: Variantにベースの変更を反映する

Prefab Variantsの利点は、ベースの変更をVariantにも反映させられるという点です。この機能のおかげで類型のPrefabの一括変更が可能になります。
今回作成したPrefabを用いて実践してみます。

![a6.PNG](https://qiita-image-store.s3.amazonaws.com/0/141004/69467350-752a-583a-d389-c96845c6b556.png)


上図のようにベースのPrefabでヒエラルキーに変更を加えました。ポップアップの右上にボタンが増えたのが分かるかと思います。
この状態でVariantであるMessagePopUpのPrefabを開いてみると

![a7.PNG](https://qiita-image-store.s3.amazonaws.com/0/141004/02a62b16-2e98-6ac2-bfc9-f1db7914731d.png)

こちらにもベースの変更が反映されます（画像では伝わりませんが...）。もちろんVariantが複数あればそれら全部に反映されます。
変更差分はコンポーネント単位で記録されるため、ベース側のオブジェクトのコンポーネントの値をVariant側でカスタムすることも可能です。

ここまでに紹介した3つの操作で一通りPrefab Variantsの基本的な運用はできるかと思います。

### 4: Prefabとインスタンスの接続解除

ここからの4と5ではPrefab Variantsというよりは2018.3でのPrefab操作の補足に寄った説明になります。

Unity2018.3以降からはPrefabについてUnpackという従来にはない操作が追加されています。

![a14.PNG](https://qiita-image-store.s3.amazonaws.com/0/141004/b5c34daf-5137-e3c9-436f-d02180f3a52a.png)


これは従来のPrefabにおける　Break Prefabに該当する操作で、シーン上のPrefabインスタンスの参照情報を消して関係のないオブジェクト化の操作を施します。

従来との違いとして、UnpackとUnpack Completelyという操作が存在しており、前者はそのUnpackしたオブジェクトの階層に変更があったとき、メニューから明示的に保存を出来るのですが、Completelyは完全にただのオブジェクト化を施すためそういった操作もできません。

この後話すNested Prefabという入れ子構造になっているPrefabの場合もただのUnpackなら入れ子それぞれのPrefabの参照は消えませんがCompletelyなら入れ子になっているものも全て1つのオブジェクト化します。

#### 

### 5: Nested Prefabでの操作
Unity2018.3のPrefabのワークフローの変化として大きいのはNested Prefabという入れ子構造のPrefabのサポートです。

従来のUnityでは入れ子構造になったPrefabは親元のPrefabとして扱われてしまうため、子のPrefabの構造を更新しても1つの入れ子Prefabでしか更新されず、入れ子に使われているPrefabの数の作業が必要となってしまっていました。
この問題を解決するために有料のアセットを用いて対処をしたりといったことをしていたのですが、ついにUnityが2018.3以降では標準でNested Prefabをサポートするようになりました。

Prefab Variantsでは、そんなNested Prefabにおいてもいくつか操作できることがあります。

![a10.PNG](https://qiita-image-store.s3.amazonaws.com/0/141004/e4d1f7db-050d-ca05-385d-61e172432113.png)

上図は4の紹介までに使ってきたベースのPrefabについて入れ子構造にしたものです。
BasePopUp内には　HeaderというPrefabが、さらにその中にはClose ButtonというPrefabが配置されています。
まず、ベースについては、これらの階層に編集を加えた場合、変更部の親への反映などを操作することが出来ます。これはNested Prefabをサポートしたことによって拡張された操作です。

![a11.PNG](https://qiita-image-store.s3.amazonaws.com/0/141004/b26ec449-aff3-6025-55d1-a5f0ae17e300.png)

入れ子になっているPrefabの変更部について右クリックでメニューを開くと、上図のように変更した部分についてそれぞれの影響するPrefabに対して変更を保存することが出来ます。
これはPrefab Variantsでも同様で、Variantの変更に対して、入れ子になっているPrefabやベースへの反映を右クリックから行うことが出来ます。（下図）

![a13.PNG](https://qiita-image-store.s3.amazonaws.com/0/141004/06b43ac2-69b5-89b8-fb17-1aadd68083d6.png)

Nested Prefabはプロジェクトの肥大化などに伴うPrefabの量産化においてかなり役に立つ機能なので、積極的に活用していきたいですね。

#### 



## まとめ

従来のUnityでは似たようなPrefabを量産する際に、ベースを作成するコストがPrefabの数だけ必要となっていました。
開発規模が小さめならまだいいのですが、これがある程度の規模になってくると中々に厄介なコストとなってきます。特に開発が進んでいる状況でベースとなる部分が改修することになると、それに派生するPrefab全てを手直しするという大変面倒な作業が発生してしまいます。
そういった作業で頭を抱えていた方はぜひ使ってほしい機能の一つです。

Unity2018.3ではこういったPrefab周りの改修がかなり入っているので、積極的に使っていきたいです。
しかし、前述の赤字で示唆したPrefab Mode等のように操作系がそもそも変わってる部分も存在しているので、チーム開発で2018.3へのアップデートを試みるときは少し注意が必要ですね。