このブログで使用しているUnityのVer
・Unity 6000.0.33f1

ちーっす!夜中にブログ書いているから変なテンションになりがち、えきふるです!
ゲームを作っていて、途中から
「おいおい、これ属性足した方が面白いんじゃないか?」とか
「あ、この種類の敵のステータス変えた方がいいな」とか
「似たような敵キャラ沢山作るのもう疲れたな」とか、ありますよね?
でも走り始めちゃったらもう戻れないんですよね。「今からステ全部変えるぅ!?無理無理!」みたいな。
…いえ、プレハブを使えば元のテンプレートを修正するだけでそこから生まれたオブジェクト全てに反映されるので対応可能です!
・毎回同じオブジェクトを作り直すのが面倒
・オブジェクトの数が多すぎて管理が大変
・手動でオブジェクトを配置するのは数が多くて大変
それでは、しっかりここで覚えていきましょう!
プレハブ(Prefab)とは?特徴とメリット
プレハブとはオブジェクトのテンプレートのようなものです、
このテンプレートを元にすることでオブジェクトの再利用を可能にする仕組みのことです。
・テンプレートを修正すれば全てのオブジェクトに修正が反応される
・プレハブをスクリプトで生成して一度に大量に配置ができる
・元データは1つなのでパフォーマンス向上が期待できる
基本的には「繰り返し使うオブジェクト」の管理のために使用すると考えれば問題ないかと思います。

これらは全てプレハブ化したオブジェクトで再利用(インスタンスと言います)することで、対応できます。

それではプレハブの使い方を見ていこー!
プレハブの使い方
プレハブの使い方を具体例をみながら確認していきましょう。
プレハブの作成方法
プレハブの作り方は非常に簡単です。
1.シーン上にオブジェクトを配置します。
↓Hirarchyに画像を置きました

2.シーンに置いたオブジェクトをProjectウインドウにドラッグ&ドロップ
↓ドラッグ&ドロップすると立方体のアイコンのデータ(プレハブ)が作成されます

3.この時点で自動でプレハブが作成されました!
↓プレハブを作る一連の動き

プレハブの元になるゲームオブジェクトは
・プレハブ化する前にシーン上で各種設定をする
・プレハブ化した後に編集
どちらでもOKです!
プレハブの再利用方法
プレハブの再利用(インスタンスの作成)の方法も非常に簡単です。
作成したプレハブデータをProjectウインドウからHierarchyウインドウにドラッグ&ドロップするだけ。

この時、複製したプレハブのInspectorの「Prefab」欄が親となるプレハブの名前になっていればOKです。
なお、Hierarchyウインドウで直接プレハブをコピペで増やしても作成できます。
プレハブの編集方法
それでは作成したプレハブの編集方法を見ていきましょう。
今、シーンに3つのオブジェクトをプレハブからインスタンスして作りました。

プレハブには2種類の編集方法があります。
1.親オブジェクトを編集して全てのプレハブに反映
2.インスタンス側の変更を親オブジェクトに反映させて全体に反映
1からみていきましょう。
1.親オブジェクトを編集して全てのプレハブに反映
まず、テンプレートにした親オブジェクトの編集画面へのアクセスの仕方が3通りあります。
1.Hierarchyウインドウのプレハブ(どのプレハブからでもOK)の「>」マークをクリック

2.プレハブオブジェクトのインスペクターの「Open」をクリック

3.Projectウインドウから元になっているプレハブデータをダブルクリック

上記のいずれかで編集画面に遷移できます。
プレハブ編集画面に遷移したら、この中で何か弄ってみましょう!

ここでの編集は元データの編集になるので、全ての子プレハブに反映されることが確認できます。

2.インスタンス側の変更を親オブジェクトに反映させて全体に反映
1.では親側を編集して子供側に反映させていましたが、逆向きでの反映も可能です。
やり方は簡単で、子供側をシーン上で編集したら
Inspectorの「Overrrides」から「Apply All」を選択すると親オブジェクトに反映がアップコンバートされます。

実際に反映される様子を下記で確認できます。

なお、「Apply All」ではなく「Revert All」を選ぶと編集内容が元に戻ります。
スクリプトでプレハブのインスタンスを作成
ここまでで、手動でプレハブを配置、編集するやり方を見ていきました。
次にスクリプトでの生成を見ていきましょう。
プレハブの生成はInstantiate()メソッドを使います。
GameObject Instantiate(Object original, Vector3 position, Quaternion rotation, Transform parent);
という形で記述します。日本語にすると
GameObject Instantiate(生成するプレハブ, 位置, 回転, 親の指定);
という感です。
Transform parent
は親にしたいオブジェクトを指定してあげると子としてHierarchyで整理されて生成されます。
↓みたいな感じでtransform.SetParent()
を使って記述します。
void Start()
{
GameObject enemy = Instantiate(enemyPrefab, new Vector3(0, 0, 0), Quaternion.identity);
enemy.transform.SetParent(parentTransform); // 親オブジェクトの子にする
}
実際にプレハブの生成サンプルとして下記のようなものを用意してみました。
このスクリプトでは一定間隔にランダムに敵オブジェクトを生成していくようなイメージです。
using UnityEngine;
public class NewMonoBehaviourScript : MonoBehaviour
{
public GameObject enemyPrefab; // 生成するプレハブ
public float spawnInterval = 1f; // 生成間隔
void Start()
{
InvokeRepeating("SpawnEnemy", 0f, spawnInterval); // 一定間隔で敵を生成
}
void SpawnEnemy()
{
Instantiate(enemyPrefab, new Vector3(Random.Range(-5f, 5f), 0, 0), Quaternion.identity);
}
}
このスクリプトをシーンの適当な空オブジェクトにアタッチ、コンポーネントの「Enemy Prefab」に生成したいプレハブを設定します。

この状態でゲームをプレイしてみましょう。

ランダムにプレハブが生成されました!
TIPS:プレハブバリアント
プレハブバリアントという概念にも少し触れておきます。
これは継承元のプレハブから派生して生成されたプレハブをさらに新たな親としてプレハブを生成する事です。

要するに孫ですね。
こうすることで1つのマスタープレハブデータから様々な亜種を生み出す事が出来るんですね。
TIPS:プレハブの解除
プレハブ化を解除して単一のゲームオブジェクトとして扱うようにする方法です。
Hirarchyで解除したいプレハブを選択、右クリックして
「Prefab」→「Unpack」で解除できます。

なお、その下の「Unpack Completely」ではプレハブをさらにプレハブ化したりといった多階層の構造の時(上記のプレハブバリアント)にその全てを一度に解除するためのものになります。
終わりに
いかがだったでしょうか?なんだか難しそうな雰囲気ですがいざ使ってみたら簡単だったのでは無いでしょうか。
PrefabはUnityでゲーム開発する場合ほぼ必須なのでは?と思えるほどよく使う機能です。
ここでサクッと把握できたらどんどん使っていきましょ〜!
当ブログ「えきふるゲームラボ」では出来るだけ分かり易く読みやすい記事の作成を目指しています!
もし読んでくださった方の中で
「ここが良く分からなかった」「ここをもう少し掘り下げて欲しい」等ありましたら
ぜひコメントで教えて下さい!

コメント貰えると元気も出ますので、どうぞお気軽にお願いしますふる!
※このブログは、UnityTechnologiesまたはその関連会社が後援または提携しているものではありません。
「Unity」は、UnityTechnologiesまたはその関連会社の米国およびその他の国における商標または登録商標です。