Unity入門 - Prefabをスクリプトから操作する -
初めに
Prefabをスクリプトから生成、操作する方法を解説します。
Prefabとはどのようなものか、Prefabの作り方、使い方については前回の記事をご覧ください。
fineworks-fine.hatenablog.com
Index
生成(Instantiate)
Prefabからオブジェクトを生成するには、Instantiate関数を用います。
今回は、Prefab化したCubeをスクリプトから生成してみます。
- GameObjectに次のスクリプトをアタッチする
using System.Collections; using System.Collections.Generic; using UnityEngine; public class CubeInstScript : MonoBehaviour { //InspectorからPrefabを取得する public GameObject PrefabCube; void Start() { //Instantiate(インスタンスにするオブジェクト) GameObject _prefabcube = Instantiate(PrefabCube); } }
- スクリプトをアタッチしたオブジェクトにPrefabを取得させる
実行すると、Cubeが生成されます。
Instantiate関数の引数について
上の説明では、Instantiate関数の引数をGameObjectのみとしていましたが、PositionやQuaternion(回転)、親オブジェクトを引数に追加することもできます。
using System.Collections; using System.Collections.Generic; using UnityEngine; public class CubeInstScript : MonoBehaviour { public GameObject PrefabCube; //Inspectorから親オブジェクトとなるオブジェクトを取得 public GameObject Parent; // Start is called before the first frame update void Start() { //Position(2, 0, 0), 回転せずに生成 GameObject _prefabcube1 = Instantiate(PrefabCube, new Vector3(2, 0, 0), Quaternion.identity); //Position(0, -2, 0), x軸に関して30度, y軸に関して45度回転させて生成 GameObject _prefabcube2 = Instantiate(PrefabCube, new Vector3(0, -2, 0), Quaternion.Euler(30, 45, 0)); //Parentというオブジェクトの子オブジェクトとして生成 GameObject _parfabcube3 = Instantiate(PrefabCube, Parent.transform); } }
Instantiate関数、Quaternionについての公式の説明は下記リンクからご覧いただけます。引数など参考になるかと思います。
Prefabをスクリプトから扱う際の注意点
Prefab自身を変更したのか、インスタンス(実体)を変更したのかの違いを明確にしておきましょう。
Prefabをスクリプトから変更する
次のスクリプトをGameObjectにアタッチして実行してみます。
using System.Collections; using System.Collections.Generic; using UnityEngine; public class CubeInstScript : MonoBehaviour { public GameObject PrefabCube; // Start is called before the first frame update void Start() { //生成(1個目) GameObject _prefabcube1 = Instantiate(PrefabCube, new Vector3(-2, 0, 0), Quaternion.identity); //Prefabの書き換え PrefabCube.transform.localScale = new Vector3(1, 2, 1); //生成(2個目) GameObject _prefabcube2 = Instantiate(PrefabCube, new Vector3(2, 0, 0), Quaternion.identity); } }
実行すると次のようになります。
2個目の生成の前にPrefabを書き換えたため、1個目と2個目で大きさが変わっていることがわかります。
また、もう一回実行すると次のようになります。
1回目の実行で、すでにPrefabを書き換えているため、このような挙動になります。
インスタンスをスクリプトから変更する
GameObjectにアタッチするスクリプトを次のように変えてみます。
using System.Collections; using System.Collections.Generic; using UnityEngine; public class CubeInstScript : MonoBehaviour { public GameObject PrefabCube; // Start is called before the first frame update void Start() { //生成(1個目) GameObject _prefabcube1 = Instantiate(PrefabCube, new Vector3(-2, 0, 0), Quaternion.identity); //インスタンスのScaleを変更 _prefabcube1.transform.localScale = new Vector3(1, 2, 1); //生成(2個目) GameObject _prefabcube2 = Instantiate(PrefabCube, new Vector3(2, 0, 0), Quaternion.identity); } }
実行すると、次のようになります。
Prefabは変更していないので、2個目を生成するときは、Prefabのまま生成されます。また、何回実行しても、Prefabは変化していないため、実行結果は同じになります。
実験
Prefab化しているCubeにRigidbodyを付け、次のようなスクリプトをGameObjectにアタッチして、実行した場合どのようになるでしょうか。
using System.Collections; using System.Collections.Generic; using UnityEngine; public class CubeInstScript : MonoBehaviour { public GameObject PrefabCube; // Update is called once per frame void Update() { Instantiate(PrefabCube, Vector3.zero, Quaternion.identity); } }
実行結果
Updateに書かれているため、毎フレームに一個、Cubeが生成されています。Rigidbodyをつけているため、物理演算も働いています。そのため、Cube同士が反発しあって、このようになります。
最後に
Prefabは敵の生成やシューティングゲームの玉などに使われます。使い方は無限にあるので、分かりにくくても使いこなせるようになることをお勧めします。