今回はUnityの基本的な機能であるプレハブについて解説していこうと思います。
実はUnity2018.3でプレハブに関する大きなアップデートがあり、使用感が違ったものになっています。その為、別々に解説していきます。Unity2018.3より前のバージョンでの使い方はコチラでまとめているので対象の方は↑から飛んでください
↑の動画でも解説していますので、是非ご活用ください。お使いのUnityが2018.3以降の場合、今回の解説は動画の方がわかりやすいかもしれません。
この記事は本のように順を追って解説しています。この記事は途中のページになります。
この記事を見ていて、現在の状況がわからない場合や忘れてしまった事などが出てきたら↓のリンクから目次ページへ飛べますので立ち戻って見てください。
<プレハブとは>
Unityでゲームを作る際、ゲームオブジェクトを複製して使い回すということはよくあることです。
例えばアイテムを複数複製していろんな場所におくなどなど、いろいろあります。
しかし、ただコピーして複製しているだけでは、複製したものも含めて全部変更したい時、全部に変更を適応しなければなりません。これは大変です。
その為、これを便利にするため、Unityではプレハブ(Prefabs)という機能を使用します。
プレハブを例えていうと、「元ファイル」と思ってもらってもいいかなーと思います。複製する元のファイルですね。
コピペとの違いは、この元ファイルに変更を加えると、複製された物にも変更が適用されるという点です。
これを使う事によって同じオブジェクトを使用する際に大変便利です。
<プレハブを作ってみよう>
あーだこーだ言っててもわからないと思うのでとりあえずやってみましょう。
とりあえず、Cubeを作りましょう。

これを複製の元にしても、右クリックしてCubeを作るのと一緒なのでちょっとパラメータをぐちゃぐちゃにいじってみましょうか。

さて、適当にいじってみました。縦長にして、マテリアルも変更し、当たり判定が変な位置にあります。皆さんも適当でいいのでいじくってみてください。
これでこのCubeはオリジナルな物になりました。これをもう一回作ろうとするとちょっと大変です。
そうしたら、これをヒエラルキーからプロジェクトウィンドウにドラッグ&ドロップします。

はい、これでプレハブが完成しました。
さて、この時ヒエラルキーのCubeを見てみましょう。

青色になっているのがわかりますね。この状態になっていると、プレハブが存在する=元になっているファイルが存在するという状態になります。
では、今度はプロジェクトウィンドウからヒエラルキーにドラッグ&ドロップしてみましょう。
シーンビューに直接ドラッグ&ドロップしてもOKです。

このようにプレハブを使って、複数のゲームオブジェクトを複製することができます。
今回はゲームオブジェクト単体のパラメータをいじってプレハブにしましたが、子オブジェクトもプレハブの中に入れることができるので覚えておくといいと思いますよ。
<プレハブを変更してみよう>
今度は、元ファイルとなっているプレハブそのものに変更を加えたらどうなるか見てみましょう。
プロジェクトウィンドウでプレハブにしたCubeを選択してください。

インスペクターにOpen Prefabというボタンがあると思うのでクリックしてください。プロジェクトウィンドウのCubeをダブルクリックしても同じ挙動になります。
ちなみにこれはヒエラルキーのプレハブの「>」となっているところを押しても同じです。

するとヒエラルキーとシーンビューが変更されます。

2つのウィンドウの上の方にプレハブの青い箱とCubeと書いてあるので、今、この状態はプレハブのCubeを編集している画面だということがわかります。
ヒエラルキーとシーンビューを使用していますが、現在はシーンの編集ではなくプレハブを編集する画面になっていますので、お間違いのないようにお願いします。
この画面をプレハブモードと言います。説明は↓の記事で解説しているので、詳しく知りたい方は参考にしてみてください。
では、この画面でプレハブを編集してみましょうか。また適当でいいのでごちゃごちゃにいじって、今の状態とは違う状態にしてみてください。

とりあえず自分はペシャンコにしてみました。
そうしたら、ヒエラルキー上の「<」となっているボタンか、シーンビュー上の「Scenes」となっているボタンをクリックしてください。どっちも一緒の機能です。

これでプレハブモードから普通のシーンビューに移ることができます。
するとさっきまで縦長だったCubeが全部ぺちゃんこになっていました。

このようにプレハブを触ることによって、複製したゲームオブジェクト全てに変更がかかることがわかりました。
<プレハブを解除しよう>
さて、プレハブで複製してみたはいいものの、このオブジェクトは他のオブジェクトと同じように変更したくない場面というのも出てくると思います。
そういった場合は、プレハブとの繋がりを解除しましょう。
ヒエラルキーでプレハブとの関係を解除したいゲームオブジェクトを選択して右クリックして、Unpack Prefabを選択してください。

↓のように解除されたゲームオブジェクトが青色から白色になっているのがわかると思います。

解除されれば、プレハブに変更がされてもこのゲームオブジェクトは変更されません。
<ゲームオブジェクトに変更を加える>
さて、↑では元ファイルとなるプレハブを変更したことで全体に影響を与えていましたが、複製先のゲームオブジェクトを変更するとどうなるのでしょう?
プレハブと複製したゲームオブジェクトは繋がっているので、複製したゲームオブジェクトの方を変更したら、プレハブも変更されてしまいそうな気がしますが、そうではありません。
複製したゲームオブジェクトは各自で変更を持ちます。
↓はとりあえず、複製したゲームオブジェクト1つのパラメータを変更したものです。

このように複製されたゲームオブジェクト1個変更しても全体に反映される訳ではありません。
ちなみに、この状態でプレハブをいじっても

このように独自にパラメータをいじったオブジェクトは「いじったパラメータ部分だけ」プレハブの変更を受け付けなくなります。
いじってない部分はプレハブの変更の影響を受けます。
ちなみに、TransformのPositionとRotationに関してはローカル座標は保存されますが、ワールド座標は保存されません。
プレハブの中の子オブジェクトを動かすと、その位置と回転はパラメータをいじったとみなされますが、一番親のオブジェクトの位置と回転を動かしてもパラメータをいじったとはみなされません。
ちなみに、元のプレハブからパラメータがいじってあると、いじったパラメータは太字になります。

ビミョーに太くなっているのがわかるでしょうか。このビミョーな違いでパラメータが変更されたかどうかを見分ける必要があります。
プレハブ内の変更点を見る
Unity2018.3以降からの機能として、元のプレハブと違うパラメータが存在した時、インスペクターの左端に青線で表現されるようになりました。

わかりやすく便利になったと思います。
プレハブを使う際の注意点(マテリアルについて)
マテリアルを変更して赤色にしていましたが、このマテリアルの色をヒエラルキーのゲームオブジェクトから変えるとどうなるでしょう。
プレハブのマテリアルの色を適当にいじってみてください。

全部色が変わってしまいました。
あれ?複製されたゲームオブジェクトの変更は元のプレハブには影響しないんじゃないの?
ついでに言うと、プレハブとの関係を切ったオブジェクトも青色になっているけど、どーして?
って話なんですが、実はマテリアルはマテリアルで元のファイルがいます。
↓こいつですね。

みなさん、マテリアルを作成した時、プロジェクトウィンドウにできたファイルがあると思います。これが元のマテリアルファイルですね。
プレハブは、「何のマテリアルがついているか」という情報は保存していますが、「マテリアルの中身がどうなっているか」は保存していません。
それでもって、マテリアルはプレハブのようにたくさん複製されたわけではなく、複製されたたくさんのゲームオブジェクトたちは、1つのマテリアルを見ています。
その為、プレハブの変更うんぬんに関係なく、マテリアルを変更すると同じマテリアルを参照している全てのオブジェクトが変更されます。
<ゲームオブジェクトの変更をプレハブに適用する>
シーン上でゲームオブジェクトをいろいろいじくって、それを元のプレハブに適用したい時があったりします。その場合のやり方を説明します。
インスペクターの上の方にPrefabと言う項目があるので、その中のOverridesをクリックします。その後、Apply Allをクリックすれば、ゲームオブジェクトの変更がプレハブに適用されます。Revert Allで全ての変更を破棄して元のプレハブと同じにします。

↓変更された各項目をクリックすると
・Prefab Sourceが変更前
・Overrideが変更後
で比較する事ができます。

↓のような状態から縦長に変更した奴をApply Allでプレハブに適用すると

↓プレハブとの関係を切ったゲームオブジェクト以外がみんな縦長になって変更が適用されているのがわかります。

<Unity2018.3より前のバージョンの場合>
画像はUnity2018.3以降のバージョンになっているものもありますが、新しいバージョンの画像になっている部分の使い方は一緒なので気にしないでください。
プレハブを作ってみよう
あーだこーだ言っててもわからないと思うのでとりあえずやってみましょう。
とりあえず、Cubeを作りましょう。

これを複製の元にしても、右クリックしてCubeを作るのと一緒なのでちょっとパラメータをぐちゃぐちゃにいじってみましょうか。

さて、適当にいじってみました。縦長にして、マテリアルも変更し、当たり判定が変な位置にあります。皆さんも適当でいいのでいじくってみてください。
これでこのCubeはオリジナルな物になりました。これをもう一回作ろうとするとちょっと大変です。
そうしたら、これをヒエラルキーからプロジェクトウィンドウにドラッグ&ドロップします。

はい、これでプレハブが完成しました。
さて、この時ヒエラルキーのCubeを見てみましょう。

青色になっているのがわかりますね。この状態になっていると、プレハブが存在する=元になっているファイルが存在するという状態になります。
では、今度はプロジェクトウィンドウからヒエラルキーにドラッグ&ドロップしてみましょう。
シーンビューに直接ドラッグ&ドロップしてもOKです。

このようにプレハブを使って、複数のゲームオブジェクトを複製することができます。
プレハブを変更する方法
プロジェクトウィンドウでプレハブにしたCubeを選択してください。

すると、インスペクターに「プレハブ」のCubeの情報が出てきます。ここで注意しなければならない点はシーンに存在するゲームオブジェクトのCubeの情報ではなく、プレハブのCubeの情報が出ています。
今、シーンは次の状態になっています。

それではプレハブのインスペクターの値を適当にぐちゃぐちゃに変更してみましょう。

このように、プレハブの値を変更すると、複製した全部のゲームオブジェクトに変更が反映されているのが見て取れます。
プレハブを解除する方法
ヒエラルキーでプレハブとの関係を解除したいゲームオブジェクトを選択した状態で上部メニューのGameObject>Break Prefab Instanceを選んでください。

↓のように解除されたゲームオブジェクトが青色から黒色になっているのがわかると思います。

解除されれば、プレハブに変更がされてもこのゲームオブジェクトは変更されません。
ゲームオブジェクトに変更を加える
さて、↑では元ファイルとなるプレハブを変更したことで全体に影響を与えていましたが、複製先のゲームオブジェクトを変更するとどうなるのでしょう?
プレハブと複製したゲームオブジェクトは繋がっているので、複製したゲームオブジェクトの方を変更したら、プレハブも変更されてしまいそうな気がしますが、そうではありません。
複製したゲームオブジェクトは各自で変更を持ちます。
↓はとりあえず、複製したゲームオブジェクト1つのパラメータを変更したものです。

このように複製されたゲームオブジェクト1個変更しても全体に反映される訳ではありません。
ちなみに、この状態でプレハブをいじっても

このように独自にパラメータをいじったオブジェクトは「いじったパラメータ部分だけ」プレハブの変更を受け付けなくなります。
いじってない部分はプレハブの変更の影響を受けます。
ちなみに、TransformのPositionとRotationに関してはローカル座標は保存されますが、ワールド座標は保存されません。
プレハブの中の子オブジェクトを動かすと、その位置と回転はパラメータをいじったとみなされますが、一番親のオブジェクトの位置と回転を動かしてもパラメータをいじったとはみなされません。
ちなみに、元のプレハブからパラメータがいじってあると、いじったパラメータは太字になります。

ビミョーに太くなっているのがわかるでしょうか。このビミョーな違いでパラメータが変更されたかどうかを見分ける必要があります。
プレハブを使う際の注意点(マテリアルについて)
マテリアルを変更して赤色にしていましたが、このマテリアルの色をヒエラルキーのゲームオブジェクトから変えるとどうなるでしょう。
プレハブのマテリアルの色を適当にいじってみてください。

全部色が変わってしまいました。
あれ?複製されたゲームオブジェクトの変更は元のプレハブには影響しないんじゃないの?
ついでに言うと、プレハブとの関係を切ったオブジェクトも青色になっているけど、どーして?
って話なんですが、実はマテリアルはマテリアルで元のファイルがいます。
↓こいつですね。

みなさん、マテリアルを作成した時、プロジェクトウィンドウにできたファイルがあると思います。これが元のマテリアルファイルですね。
プレハブは、「何のマテリアルがついているか」という情報は保存していますが、「マテリアルの中身がどうなっているか」は保存していません。
それでもって、マテリアルはプレハブのようにたくさん複製されたわけではなく、複製されたたくさんのゲームオブジェクトたちは、1つのマテリアルを見ています。
その為、プレハブの変更うんぬんに関係なく、マテリアルを変更すると同じマテリアルを参照している全てのオブジェクトが変更されます。
変更をプレハブに適用する方法
ゲームオブジェクトのインスペクターの上の方を見てみると、Prefabと言う項目があり、Select,Revert,Applyとあります。

Selectは元のプレハブのファイルを開くボタンで、Revertが全ての変更を破棄して元のプレハブと同じにします。Applyがゲームオブジェクトの変更がプレハブに適用されるボタンです。
↓のような状態から縦長に変更した奴をApplyでプレハブに適用すると

↓プレハブとの関係を切ったゲームオブジェクト以外がみんな縦長になって変更が適用されているのがわかります。

<まとめ>
プレハブを用意すると複製する時に便利だよ!
プレハブには子オブジェクトも含めることができるよ!
プレハブに変更を加えると複製されたオブジェクトにも反映されるよ!
複製されたオブジェクトは独自に変更を持つこともできるよ!
マテリアルの中身はプレハブとは関係ないよ!
と、言うわけで、プレハブの基本的な使い方でした。まだちょっと、プレハブについては解説が必要なので次回もプレハブについて解説していきたいと思います。