みなさんUnityを使っていますか?
こちらの記事を閲覧している人の多くはUnityをすでに使い始めている人だと思います。今回はそんなはUnityを使い始めた人が初期につまずきやすいInstantiateについて、わかりやすく1からまとめました!
この記事で解説する内容は、
- Instantiate関数で何が出来るのか?
- Instantiate関数の使い方
- Instantiate関数で作ったオブジェクトの名前・親子関係などの設定について
- Resources関数を使った汎用的な使い方
など、基本的な内容から、少し応用した部分まで紹介していきますので、一緒にInstantiate関数について学んでいきましょう!
まず「Instantiate関数」とは?
まずInstantiate関数とは、どんな関数で何ができるのかを見てみましょう。
何ができる関数なの?
一言でいえば、ゲーム中に表示される主人公や敵キャラクターなどのオブジェクトを生成する関数です。またこの時生成されるオブジェクトはクローンとも呼ばれたりもします。化学の分野でも、生物のコピーをクローンと呼んだりしますよね?それと同じです。
Instantiate関数は非常に使用率の高い関数なので、Unityのサンプルやチュートリアルを触っている人は、すでに目にしたことがあるかもしれませんね。Unity上でオブジェクトを作成する際には基本的にこの関数を利用することになります。
まずはInstantiate関数とはオブジェクトを生成する関数だと覚えましょう!
どんな時使うの?
プログラム上からオブジェクトの生成が行えれば、様々なことができるようになりますよ。例えばシューティングゲームで「ボタンを押したときに自機から弾を生成し発射!」なんてことが出来たりするわけです!
実際に何が起きるか見てみよう!
文字では説明しましたが、実際どんな挙動をするのか目で見てみないとわからないですよね? まずは使うと何が起こるのか簡単に画像で流れを見てみましょう。
※ここでは細かい説明は省略しますので「何が起きるのか?」に注目しましょう!
コピー元のオブジェクトを準備する
今回は「コピー本のオブジェクト」として「originObject」というオブジェクトを用意しました。
Instantiate関数を準備する
using System.Collections; using System.Collections.Generic; using UnityEngine; public class GameManager : MonoBehaviour { public GameObject originObject; //オリジナルのオブジェクト // 実行時に呼ばれる初期化処理 void Start () { Instantiate(originObject, new Vector3( -1.0f, 0.0f, 0.0f), Quaternion.identity); } }
Instantiate関数を使用し、引数に先ほどの「originObject」を引数に渡すようにプログラムを組みます。
すると・・・
実行時にクローンが作成される
実行時に「originObject」を元に「originObject(Clone)」というオブジェクトが生成されました!
このようにInstantiate関数とは「オブジェクトを元」に「オブジェクトを生成する関数」なのです。
Instantiateの詳細説明
先ほどの説明で何が出来る関数なのかは、何となく理解できたかと思います。
では次にInstantiateの具体的な使い方に入っていきましょう!
Instantiateの引数・戻り値を理解しよう!
リファレンス(公式の関数説明)を参考に、引数・戻り値について見ていきます。
必要最低限で見る引数・戻り値
// c#での記述 public static Object Instantiate(Object original); // jsでの記述 public static function Instantiate(original: Object): Object;
- 戻り値・・・既存オブジェクトのクローン
- 第1引数(original)・・・ コピーしたい既存オブジェクト
見て分かる通り「コピーしたい既存オブジェクト」を引数として渡すとクローンが作成され、「コピーされた結果の新しいオブジェクト」を戻り値として取得も出来る関数だということです。
必要最低限の引数だけで見てみると、とてもシンプルな関数ですね。
同時に座標や回転も設定できる!
// c#での記述 public static Object Instantiate(Object original, Vector3 position, Quaternion rotation); // jsでの記述 public static function Instantiate(original: Object, position: Vector3, rotation: Quaternion): Object;
戻り値・・・既存オブジェクトのクローン
第1引数(original)・・・ コピーしたい既存オブジェクト
第2引数(position)・・・新規オブジェクトの位置
第3引数(rotation)・・・新規オブジェクトの向き
第2引数、第3引数に、位置と向きを入れることもできます。クローンの作成時に、出現座標や回転を設定したい場合は、第2引数、第3引数に値を入ればいいわけです。
Instantiateの具体的な使い方!
では簡単に流して説明してしまった「実際に何が起きるか見てみよう!」の項目を細かく見ていきましょう。
※初心者のために1から詳しく書いていきます。先ほどの説明で理解できている人はこの項目は飛ばしても構いません。
空っぽのプロジェクトを作成する
まずはここから始まります。いつものように空っぽのプロジェクトを作成しましょう。
プログラム実行用のオブジェクト作成
まずはプログラムを実行させるために、ゲームの管理オブジェクトを作りましょう。Hierarchy上で右クリック →Create Empty で作成できます。
オブジェクトの名前変更
先ほど作ったオブジェクトの名前を今回はGameManagerに変更しましょう。Hierarchyから先ほど作ったオブジェクト選択し、右クリック → Renameで名前を変更できます。
無事オブジェクトの名前が変更されましたね。
プログラムの追加
②AddComponentをクリックします。すると画面のような選択肢が出てきます。
③新しくプログラムを追加しますので、NewScriptを選びましょう。
プログラムの名前は GameManagerにして、Create and Addボタンを押しましょう。
※今回は言語はc#で進めることとします。
うまくいったらGameManagerのInspector表示に GameManager(Script)の項目が追加されているはずです。
プログラムの編集
追加されたGameManager(Script)をダブルクリックしたりすると、プログラムの編集が行えます。
おそらく以下のような記述が最初からされていると思います。
using System.Collections; using System.Collections.Generic; using UnityEngine; public class GameManager : MonoBehaviour { // Use this for initialization void Start () { } // Update is called once per frame void Update () { } }
今回は以下のように編集してみましょう。
using System.Collections; using System.Collections.Generic; using UnityEngine; public class GameManager : MonoBehaviour { public GameObject originObject; //オリジナルのオブジェクト // Use this for initialization void Start () { } }
「public GameObject originObject;」 には後で「コピー元のオブジェクト」を設定します。
void Update() {} 部分を削除したのは今回は利用しないためです。また変更後はプログラムの保存を忘れず行いましょう。保存しないとプログラムが反映されません。
originObjectの設定
プログラムが正しく設定できており、保存もちゃんとされていればHierarchy上のGameManagerを選択→Inspectorウィンドウ→GameManager(Script)に「OriginObject」が設定項目として増えているはずです。
コピー元オブジェクトの作成
Hierarchy上で右クリック→3D Object→Cubeで、四角いオブジェクトを作成します。
追加されたら、今回はクローンと横並びにしてわかりやすくするために、座標は(x=1 y=0 z=0)にしておきましょう。またGameManagerの名前を変えた時と同じようにRenameを使い、名前をoriginObjectにしておきましょう。
プログラムへoriginObjectを渡す
Hierarchy上でGameManagerを選択し、表示されているGameManager(Script) の OriginObject項目へ、先ほど作成したoriginObjectをマウスの左クリックでつかんで投げ込みます。
Instantiate関数を使う
using System.Collections; using System.Collections.Generic; using UnityEngine; public class GameManager : MonoBehaviour { public GameObject originObject; //オリジナルのオブジェクト // Use this for initialization void Start () { Instantiate(originObject, new Vector3( -1.0f, 0.0f, 0.0f), Quaternion.identity); } }
再びプログラムを編集しましょう。
上記のようにInstantiate関数を記載します先ほどoriginObjectを投げ込んだので、プログラム上のoriginObjectを使えば、投げ込まれたオブジェクトへアクセスできます。これで「コピー元オブジェクト」を引数に与えられましたね!
第2引数の「new Vector3( -1.0f, 0.0f, 0.0f)」は、座標の指定です。わかりやすく「コピー元のオブジェクト」の隣に並べるために今回はこう指定しました。第3引数の「Quaternion.identity」は回転させない、という指定です。
今回は回転は必要ないためこう指定しています。
実行してみる
実際に実行してみると、無事クローンが作成できていると思います。
さらにInstantiateを使いこなそう
ここまででInstantiateの使い方は理解できたと思います。
しかしゲームを作る上では作成したオブジェクトをどう扱うのか、など考えることは山積みです。ここから先はInstantiateをもっとうまく活用するためのテクニックをまとめておきます。
戻り値を活用し名前や親子関係を変えてみよう
オブジェクトを作成したからには、それをもっとプログラムから操作したいですよね。
そこでInstantiate関数の、戻り値が活躍します。
using System.Collections; using System.Collections.Generic; using UnityEngine; public class GameManager : MonoBehaviour { public GameObject originObject; //オリジナルのオブジェクト // Use this for initialization void Start () { GameObject cloneObject = Instantiate(originObject, new Vector3( -1.0f, 0.0f, 0.0f), Quaternion.identity); // 取得した戻り値の活用例 cloneObject.name = "originObject2"; // クローンしたオブジェクトの名前を変更 cloneObject.transform.parent = this.transform; // GameManagerを親に指定 cloneObject.transform.position = new Vector3( -1.0f, 1.0f, 0.0f); // 座標を変更 } }
上記の活用例のように、戻り値をGameObjectとして受け取れます。
それに対しプログラムを書くことで「名前の変更・親子関係の操作・座標の変更」など、色々と編集が可能なわけです。取得したオブジェクトを、うまく使いこなしましょう!
プログラム上でPrefabを指定し生成する
ここは少し上級者向けの内容になるため、初心者の方は読み飛ばしても構いません。ゲームを作っていくと汎用的な処理を書くために、プログラム上でPrefabを指定して生成したい場合が出てくると思います。
その場合は Resources関数とInstantiate関数をうまく組み合わせると汎用的な生成処理がかけるでしょう。
void Shot () { GameObject prefab = (GameObject)Resources.Load ("Prefabs/Bullet"); GameObject cloneObject = Instantiate (prefab, this.transform.position, Quaternion.identity); }
Resourcesで読み込んだオブジェクトをInstantiateで生成するわけですね!
まとめ
動的なオブジェクトの生成は、ゲームを作る上でとても大切な機能です。敵の出現・弾の発射・エフェクトの表示、などなどゲームとは、オブジェクトが多用されるものだからです。
Instantiate関数をいこなして、色々なオブジェクトが入り乱れる楽しいゲームを作りましょう!