ここでは、UnityスクリプトからGameObjectを動的に生成する方法を解説していきます。また、特に初めてUnityスクリプトを扱う人を想定してUnityスクリプトの作り方も詳しく解説していますので、初めての方もここでGameObjectの生成を題材にUnityスクリプトに慣れていきましょう。
開発環境
- Unity 2019.4.1f1
プリミティブ(基本3Dモデル)をスクリプトから生成する
プリミティブとは?
Unityではプリミティブと呼ばれる、基本3Dモデルがあらかじめ用意されています。


ゲーム全体を管理するマネージャーを作成する
それでは、スクリプトからプリミティブを生成してみましょう。
Unityスクリプトは何らかのGameObjectにアタッチされた状態で動かすことができるので、まずは空のGameObjectを作成して、ゲーム全体を管理するマネージャーとしましょう。
マネージャークラスの作成については以下の記事をご覧ください。

ここでは、GameManagerという名前で空(カラ)のGameObjectを作成し、Managerという名前のスクリプトをアタッチしています。
スクリプトからプリミティブを生成する
続いて、このスクリプトを編集していきましょう。スクリプトをダブルクリックすることで関連付けられたエディターが開きます。
スクリプトからプリミティブを生成するためには、GameObjectクラスのCreatePrimitiveメソッドを用いて、その引数でどのプリミティブを生成するかを指定します。引数はPrimitiveType列挙型で指定します。
まずは、Startメソッドに以下の一文を入力して、立方体を生成させます。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Manager : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
GameObject cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
}
// Update is called once per frame
void Update()
{
}
}
これでファイルを保存してエディターをいったん閉じてみます。Unityの再生ボタン(▷)をクリックしてゲームを開始してみましょう。自動的にGame画面に切り替わり、もともとなかった立方体が画面に追加されたことが分かります。これでスクリプトからプリミティブを生成することができました。最後にもう一度再生ボタン(▷)をクリックしてゲームを終了させます。

スクリプトでPrefabからオブジェクトを生成する
Prefabとは?
UnityにおけるPrefabとはオブジェクトを作成するもとになる設計図のようなものです。プログラミングの経験があれば、「オブジェクト指向型プログラミングにおけるクラスのようなもの」といった方が分かりやすいかもしれません。複数のオブジェクトを組み合わせたり、スクリプトをアタッチしたりして複雑になったオブジェクトは、Prefabにすることで再利用が可能になり使いまわすことが可能になります。
Prefabの作成
例えば、下のように赤い球のオブジェクト(RedSphere)を作成してそれをPrefab化するには、HierarchyからProjectにドラッグ・アンド・ドロップします。

これで、RedSphereというPrefabが完成しました。Resourcesというフォルダを作成して、このPrefabをResourcesに移動させておきましょう(スクリプトから参照するときは、Resourcesフォルダを参照するため)。
Prefabからオブジェクトを生成する
このPrefabをスクリプトから生成させてみます。なお、Hierarchy上の元のRedSphereは予め削除しておきましょう(残っているとスクリプトから生成したものと紛らわしいため)。
GameManagerにアタッチしているスクリプトを以下のように変更します。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Manager : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
GameObject sphere_prefab = Resources.Load<GameObject>("RedSphere");
GameObject sphere = Instantiate(sphere_prefab);
}
// Update is called once per frame
void Update()
{
}
}
ResourcesクラスのLoadメソッドは、Resourcesフォルダ内のオブジェクトを検索するので、先ほどその中に移動したRedSphereをsphere_prefabとして読み込んでいます。ここではジェネリックメソッドを用いて、戻り値の型をGameObjectに指定しています。続いて、Instantiateメソッドでそれを複製することでPrefabをオブジェクト化させることができます。
これでゲームを開始すると、以下のようにPrefabがオブジェクト化できていることが分かります。

既存のGameObjectを複製する
GameObjectを検索して取得する
Hierarchyビューに存在するGameObjectをスクリプトから検索するには、GameObjectクラスのFindメソッドを使用します。
例えば、以下のCubeSampleというGameObjectを検索してみましょう。

このCubeSampleをスクリプトを用いて取得するには、以下のようにします。
GameObject obj = GameObject.Find("CubeSample");
取得したGameObjectを複製する
Prefabからオブジェクトを生成する際に説明したInstantiateメソッドは引数で与えられたものを複製するメソッドです。この引数にGameObjectを渡せば、そのままこのコピーが得られます。
GameManagerにアタッチしているスクリプトを以下のようにして、マネージャークラスからGameObjectを複製してみましょう。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Manager : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
GameObject obj = GameObject.Find("CubeSample");
GameObject newObj = Instantiate(obj);
newObj.transform.position = new Vector3(2, 0, 0);
}
// Update is called once per frame
void Update()
{
}
}
なお、newObj.transform.position = new Vector3(2, 0, 0);
の部分は複製したGameObjectがもとのオブジェクトと重ならないように場所をずらしています。
これで以下のように複製できました。

コメント