Unityのプレハブの作り方と使い方

Unityではプレハブ(prefab)という機能があります。

当ブログでもこのプレハブは幾度となく使用してきましたが、プレハブのみを扱う記事がなかったので改めて使ってみようと思います。

このプレハブとは一体なんなのでしょうか?

スポンサーリンク

プレハブとは!?

英語の意味から言うと『組み立て式の家屋』という意味で世間一般で言うプレハブ小屋と同じ意味で問題なさそうです。

発音的にはプリファブのようですが・・・、わかりやすくプレハブとして進めましょう・・・(-_-)

Unityのプレハブは『組み立てられた物』という認識でいいと思います。

例えば銃から弾を何発も打つ、主人公キャラクターがある範囲に突入したら敵を新しく出現させる。

こういった場合はあらかじめシーンに弾や敵を置いておく事は出来ません(見えないようにしておいて必要に応じて表示する方法はあり)。

その為、弾を銃口の先から登場させる、敵を決められた場所に登場させる、という事をしなければいけません。

こういった場面で使うのがプレハブで、スクリプトから出現させます。

つまり『弾』や『敵』をプレハブとして作成しておき、決められた場所にスクリプトから登場させてやるわけです。

弾や敵のプレハブはひな型(タイ焼きの鉄板のようなもの)でそれを使ってインスタンス(それぞれのタイ焼き)を生産していきます。

プレハブの利点としてはあらかじめゲームオブジェクトをシーン上に配置しておかなくていいというだけでなく、

同じ物を大量にゲームに登場させたい時にもスクリプトを使ってプレハブからインスタンスを生成し使う事が出来ます。

ゲームオブジェクトをプレハブにする

プレハブを機能と言っていますが、そんな大それた意味として考える必要はなく、一まとまりの機能を持ったゲームオブジェクトの集まりとして考えると良いと思います。

例えば人型のモデルをシーンに配置し、そのモデルにコライダ(当たり判定部分)やスクリプトを取り付け敵として主人公を追いかけるようにします。

このように一まとまりの機能を取り付けた敵キャラをプレハブとすれば、必要に応じて主人公を追いかける敵キャラをゲーム内に登場させる事が出来ます。

ではどうやってプレハブ化すればいいのでしょうか?

実はものすごく簡単に出来ます。

プレハブの作成の仕方

プレハブファイルを作成する場合はProjectタブ内で右クリック→Create→Prefabを選択します。

右クリックメニューからプレハブを作成

↑のようにメニューが出るのでPrefabを選択します。

プレハブファイル

するとNew Prefabというファイルが作成されます。

これが空のプレハブファイルとなるので、後はプレハブにしたいゲームオブジェクトをそのファイルにドラッグ&ドロップするだけで、そのゲームオブジェクトがプレハブになります。

実はこの工程、やる必要がないんですが・・・・(^_^;)

プレハブファイルを作成しなくても、プレハブにしたいゲームオブジェクトをそのままProjectタブのエリアにドラッグ&ドロップすればプレハブが作成されます。

いちいち最初に空のプレハブファイルを作成しなくても出来ます(^_^)v

実際にゲームオブジェクトをプレハブ化する

文章を見てもわからない事もあると思うので、実際にシーンに配置したゲームオブジェクトをプレハブにしてみましょう。

ヒエラルキー上で右クリック→3D Object→Sphereを選択し名前をBallとします。

またゾンビのモデルをシーン上に配置し、CharacterControllerコンポーネントの取り付けや移動スクリプトの取り付けをします。

敵キャラクターの移動に関しては

Unityで敵キャラを登場させて、目的地に移動させる
敵キャラクターをシーンに配置し、動かす為のコンポーネントであるキャラクターコントローラーを取りつけ、目的地に向かって移動するようなスクリプトを作成して動かします

等を参考に作成してください。

今回はプレハブの機能についてなのでBallの設置のみで敵キャラクターをプレハブ化しなくても問題ありません。

敵キャラクターもプレハブ化して使う事が出来るというのを確認する為に登場させただけです。

プレハブにするゲームオブジェクト

↑がプレハブ化するボールと敵キャラクターを配置した時のヒエラルキーです。

Main CameraやDirectional Lightは最初から設置されており、Cubeは床に使用しています。

プレハブにするボール

プレハブにするBallはSphereの名前を変えただけなので↑のようなインスペクタの表示になっているはずです。

プレハブにする敵

プレハブにする敵キャラクターにはCharacterControllerコンポーネントの取り付けとコライダのサイズや位置調整、カメラの方向に向かっていくスクリプトPrefabMoveスクリプトを取りつけています。

PrefabMoveスクリプトは

↑のようにしました。

正直なところ登場してからカメラ方向に移動する為だけに作ったものなので中身は気にしないでください・・・・(^_^;)

ちゃんとしたスクリプトではないので・・・・(-_-)

プレハブにするゲームオブジェクトのサンプル

↑がプレハブ化するボールと敵の実際の画面です。

このBallと敵キャラのz@walkをProjectタブの領域にドラッグ&ドロップしましょう。

Ballはさきほど作成したNew Prefabファイルに、z@walkは何もない空間にドラッグ&ドロップします。

Projectタブ領域にドラッグ&ドロップ

New PrefabファイルにBallをドラッグ&ドロップするとプレハブのファイル名はそのままNew Prefabとなり、z@walkを何もない領域にドラッグ&ドロップすると名前がそのままのプレハブファイル名となります。

これでゲームオブジェクトをプレハブにする事が出来ました。

ゲームオブジェクトへの変更をプレハブに反映させる

ゲームオブジェクトをプレハブ化した後に元のゲームオブジェクトに変更を加えそれをプレハブに反映させたい事があります。

Ballのサイズを変更しそれをプレハブに反映させてみます。

元のゲームオブジェクトを変更

↑のようにBallのインスペクタでScaleをすべて0.5に変更します。

ボールプレハブのデータ

現時点では↑のようにBallのプレハブであるNew PrefabのScaleは変更されていません。

インスペクタのRevert、Applyボタン

BallのインスペクタのRevertを押すと変更を加えたところがプレハブのデータに戻ります。

Applyボタンを押すとBallに変更を加えた部分がプレハブへと反映されます。

当然の事ながらプレハブに変更を加えるとプレハブから作成したゲームオブジェクトすべてに変更が反映されてしまいますので注意が必要です。

それではBallのインスペクタのApplyボタンを押して変更をプレハブに反映してみましょう。

プレハブにデータが反映される

↑のようにプレハブであるNew PrefabのScaleが0.5になったことを確認出来ます。

プレハブを使ってみる

プレハブの作成と編集のやり方がわかったところで、実際にプレハブを使ってみましょう。

手動でプレハブからゲームオブジェクトを作成

まずは手動でプレハブからゲームオブジェクトを作成してみましょう。

まぁ・・・説明もいらないほどなんですが、プレハブファイルをヒエラルキー上にドラッグ&ドロップするだけです!

ボールのプレハブであるNew Prefabを2つヒエラルキー上にドラッグ&ドロップしてみましょう。

ボールプレハブをシーン上に配置

↑のようにプレハブからゲームオブジェクトの作成が出来ました。

プレハブから作成したゲームオブジェクトは元のBallオブジェクトと同じ情報を持っているので、設置される場所はプレハブ化したBallの位置と同じ場所になります。

プレハブから作成したゲームオブジェクトに変更を加え、インスペクタでApplyボタンを押すとプレハブが変更されてしまう為、注意する必要があります。

プレハブからゲームオブジェクトを作成する関数を見てみる

次にスクリプトを使ってプレハブからゲームオブジェクトを作成してみましょう。

まずはプレハブからゲームオブジェクトを作成する関数を見てみます。

↑のように第1引数にプレハブのゲームオブジェクト、第2引数はゲームオブジェクトの位置、第3引数はゲームオブジェクトの角度です。

実際の値を設定し使うとしたら

↑のようにインスペクタで設定したプレハブをこのスクリプトが設定されているゲームオブジェクトの位置(transform.position)と、

Quaternion.identityで角度を指定しゲームオブジェクトを作成する事が出来ます。

Quaternion.identityは親要素の角度に合わせるので親があれば親の角度、なければワールド座標(X、Y、Zの角度が0)になります。

C#でスクリプトを記述する場合、Instantiateの戻り値はObject型となっている為GameObject型にキャストする必要があります。

↑のように明示的にキャストします。

プレハブからゲームオブジェクトを生成するサンプルの作成

それでは実際にプレハブからゲームオブジェクトを生成しゲームに登場させるサンプルを作成してみましょう。

ゲーム全体で使用するスクリプトを管理するManagementオブジェクトの作成

まずはゲーム全体で使用するスクリプトを設定する空のゲームオブジェクトを作成します。

スクリプトはその動作をさせるゲームオブジェクトに設定していくのが普通ですが、全体を管理するスクリプト等は空のゲームオブジェクトを作成し、

そこに取り付けておくとわかりやすいです。

ヒエラルキー上で右クリック→Create Emptyを選択し、名前をManagementとします。

プレハブからゲームオブジェクトを生成するCreateスクリプトの作成

次にManagementゲームオブジェクトにプレハブからゲームオブジェクトを生成するCreateスクリプトを作り取りつけます。

今回の例ではCreateスクリプトはゲーム全体を管理するようなスクリプトではありません。

public変数でボールプレハブと敵プレハブを設定出来るようにします。

ボールプレハブはゲームに設置した床のゲームオブジェクトをマウスクリックしたときにその場所に表示し、

敵プレハブは一定時間毎に登場するようにします。

Update関数内でマウスの左クリックを押された時の処理をしていますが、ここでメインカメラからマウスクリックした位置にレイを飛ばしています。

レイが『Field』レイヤーが設定されたゲームオブジェクトに接触したらそこにボールプレハブからゲームオブジェクトを生成しています。

作成したボールプレハブが増え過ぎると困るのでDestroy関数を使用して今作成したゲームオブジェクトが5秒後に消えるようにしています。

敵プレハブはインスペクタで設定した秒数を経過したらゲームオブジェクトを生成しています。

Random.Range関数の引数は

Random.Range(最小値, 最大値);

でint型の値を設定すると最小値と最大値を含まない範囲のランダムな値を得られ、float型の値を設定すると最小値と最大値を含む範囲のランダムな値が得られます。

なので、X軸とZ軸にランダムな値を与えて敵の登場位置を変更しています。

敵キャラクターもわんさか増えると邪魔なので50秒後には消すようにしてます。

C#でCreateスクリプトを書き換えたCreateCスクリプトの作成

今回のスクリプトをC#で書こうとするとInstantiate関数とPhysics.Raycast関数の部分でつまづく人もいると思うのでC#で書き換えたスクリプトも載せておきます。

JavaScriptとC#の読み替えに関しては

UnityのJavaScriptとC#を読み替えてどちらでも対応出来るようにする
UnityのJavaScriptとC#を読み替えてどちらでも対応出来るようにする。Unityでは特殊なJavaScriptとC#でプログラミングする事が出来ますが、この違いがわからずC#をJavaScriptで読み替える事が出来ない事があります。そんな時にそれぞれの言語を読み替えられるように違いを調べてみます。

を参照してください。

行っている処理はJavaScriptで記述したものと同じなので詳細は省きます。

プレハブからゲームオブジェクトが生成されるか確認する

これでスクリプトが完成したのでManagementゲームオブジェクトに設定しインスペクタでプレハブと秒数の設定をしてください。

プレハブをインスペクタで設定

これでインスペクタの設定が出来ましたのでUnityを実行して確認してみましょう。

プレハブのサンプル

床をクリックするとそこにボールゲームオブジェクトが登場し、5秒後に消えています。

またゾンビはインスペクタで設定した5秒間隔で登場しているのが確認出来ます。

オブジェクトの親を設定する

さきほどのスクリプトでは位置と回転を設定しプレハブからインスタンスを生成していましたが、すべてのインスタンスに親が設定されていませんでした。

インスタンスを何らかのゲームオブジェクトの子要素にしたい時もあると思います。

そんな時は

プレハブをインスタンス化した後にそのインスタンスを5秒後に削除していましたが、その前にSetParentを使って親要素をこのスクリプトのtransformを指定します。

するとCreateスクリプトが設定されているのはManagementゲームオブジェクトなので生成するインスタンスの親がManagementになります。

ボールのインスタンスの親をManagementにしてみましょう。

ボールのインスタンスを生成した後に先ほどのobj.transform.SetParent(transform)を追加してください。

インスタンスの親要素を設定

↑のように床をクリックしてボールのインスタンスを生成すると親要素がManagementになっています。

ゾンビの方は親要素を指定していないので親がない状態で生成されています。

プレハブは便利

今回、あらためてプレハブを使ってみましたが、やっぱり便利ですね。

記事内でも触れていますが、弾を発射する時や同じ敵を量産したい時にプレハブが使えると非常に楽になります。

また、エフェクトを表示したい時にもInstantiateを使ってそのエフェクトを表示したい場所に表示すると言う事も出来ます。

つまりプレハブは今まで使っていたものとまったく別の機能ではなくただのゲームオブジェクトの集まりであるという事ですね。

試しにManagementのインスペクタでNew Prefabの代わりにProjectsタブのAssetsエリアにある他のゲームオブジェクトを設定して確認してみてください。

床をマウスクリックするとそのゲームオブジェクトがボールの代わりに表示されるはずです。

この記事では実用的なサンプルを使っていませんが、実用的なサンプルは他の記事にたくさんあるので参考にしてみてください。

スポンサーリンク

記事をシェアして頂ける方はこちら

フォローして頂くとやる気が出ます