【Unity】Instantiate関数の使い方を知ってオブジェクトを生成しよう!

Instantiate関数の使い方 Unity

こんにちは、ともくんのゲーム作り部屋にようこそ!

このページでは、

「UnityでInstantiate関数の使い方が分からない。」

「Instantiate関数ってどんな時に使ったら良いの?」

というお悩みの方に向けた内容となっています。

Instantiate関数は、Unityでオブジェクトを新しく生成する処理を行ってくれるメソッドです。

例えば、シューティングゲームなどで、弾を撃つのにボタン操作に合わせて弾のオブジェクトを表示させる、といったオブジェクトを新たに生成する際に、Instantiate関数が使われます。

また、多くの場合でUnityのPrefabの機能と合わせて、使われることが多いです。

そこで、このページでは、UnityのInstantiate関数について、どんな機能があるのか、また使い方や実用例を紹介していきます。

なお、このページでは、

Windows11
Unity Hub3.11.0
Unity6

のバージョンで解説しています。

この記事を書いた人

ゲーム作りを学び始めた一児のパパです。
このブログは、子供から「ゲームを作ってみたい!」と言われ、非プログラマーでゲーム作りをしたことない僕が、ゲーム作りの本を読んで独学でゲーム開発を学んでいるブログです。
同じように初めてゲーム作りをしている方と一緒に学んでいけるようなブログに出来たらいいなと思っています。
また、「このコードはおかしい」とか「もっと良い書き方があるよ!」などあれば、どんどん指摘して頂けると助かります。

Instantiate関数とは?オブジェクトを新しく生成する

Instantiate関数は、冒頭でも紹介した通りで、新しいオブジェクトを生成することができるメソッドになっています。

Instantiateは、日本語でインスタンス化という意味がありますが、インスタンスとは実際に作ったもののことを指していて、オブジェクトを生成するというところに繋がります。

例えば、

といった際に、Instantiate関数を使うことで、オブジェクトを新しく作ることができます。

Instantiate関数の使い方

それでは早速、Instantiate関数の使い方を解説していきます。

引数に生成したいオブジェクトを指定する

Instantiate関数は、引数に生成したいオブジェクトを指定することで、新しくそのオブジェクトを生成させることができるというメソッドになっています。

Instantiate(生成したいオブジェクト);

この生成したいオブジェクトは、GameObject型で指定していくことになります。

例えば、ゲーム内に配置している「player」を新たに生成したい場合は、

using UnityEngine;

public class InstantiateManager : MonoBehaviour
{
    GameObject player;	// GameObject型の変数を宣言

    void Start()
    {
        player = GameObject.Find("player");	// playerを探して変数に代入
    }

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))	// スペースキーを押した瞬間
        {
            Instantiate(player);	// playerを生成する
        }
    }
}

のようなスクリプトを空オブジェクトにアタッチしてあげることで、スペースキーを押す度にオブジェクトが新たに生成されていきます。

なお、生成される座標は指定した元の座標と同じになるため、動画では重なっていますが、オブジェクトが新たに生成されているのがわかります。

アウトレット接続でオブジェクトを繋ぐ

先ほど、Instantiate関数の引数にオブジェクトの指定をFindメソッドで探して設定しましたが、他にもアウトレット接続と呼ばれる方法があり、Instantiate関数を使う場合はこのアウトレット接続でオブジェクトを指定することが多いです。

アウトレット接続とは、インスペクターウィンドウ上で変数を設定する方法で、この方法を使ってオブジェクトの指定を行っていきます。

具体的には、GameObject型の変数をpublicアクセス修飾子を付けて宣言してあげることで、インスペクターウィンドウから変数を参照することができます。

using UnityEngine;

public class InstantiateManager : MonoBehaviour
{
    public GameObject player;   // publicを付けて変数を宣言する

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))    // スペースキーを押した瞬間
        {
            Instantiate(player);    // playerを生成する
        }
    }
}

実際に、このスクリプトをアタッチしたオブジェクトを見てみると、インスペクターウィンドウ上で変数を参照することができます。

そして、この変数の横に、生成したいオブジェクトをドラッグ&ドロップしてくることで、変数にオブジェクトを設定することができます。

なお、Prefab化したオブジェクトを生成したい場合は、このドラッグ&ドロップの際に、アセットフォルダ内からPrefab化されたオブジェクトを指定してあげることができます。

これが、アウトレット接続と呼ばれる方法で、Instantiate関数を使ったオブジェクト指定でよく使われる方法です。

第二引数以降で親子関係や座標・回転量を決められる

Instantiate関数は、引数にオブジェクトを設定することで、生成するオブジェクトを指定することができますが、他にも第二引数以降で生成する座標回転量親オブジェクトの中に入れるかなどの情報を指定してあげることができます。

具体的には、

  • Instantiate(Object, Transform);
  • Instantiate(Object, Transform, bool);
  • Instantiate(Object, Vector3, Quaternion);
  • Instantiate(Object, Vector3, Quaternion, Transform);

と、引数の書き方にいくつかパターンがあります。

なお、このように引数の形で処理が変わるものを、メソッドのオーバーロードと呼びます。

Instantiate(Object, Transform);

生成するオブジェクトをどの親オブジェクトの中に生成するか、第二引数のTransform型で指定することができます。

Instantiate(生成したいオブジェクト, 親オブジェクト);

例えば、Parentという親オブジェクトの中に生成したオブジェクトを入れたい場合は、

using UnityEngine;

public class InstantiateManager : MonoBehaviour
{
    public GameObject player;   // publicを付けて変数を宣言する
    public Transform parent;    // 親オブジェクト用にTransform型の変数を宣言する

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))    // スペースキーを押した瞬間
        {
            Instantiate(player, parent);    // parentを親としてplayerを生成する
        }
    }
}

という形で書いてあげて、先ほどと同じくアウトレット接続してあげることで、Parentの中にオブジェクトが生成されるようになります。

Instantiate(Object, Transform, bool);

先ほどの形に、さらに第三引数にbool値を付けてtrueを指定した場合、親オブジェクトの中に生成するが、そのオブジェクトにワールド座標を維持させることができます。

Instantiate(生成したいオブジェクト, 親オブジェクト, ワールド座標を維持するかどうか);

通常、このbool値を引数に付けていない場合、もしくはfalseを引数につけた場合は、親オブジェクトを中心としたローカル座標でオブジェクトが生成されますが、引数にtrueを指定してあげることで、ゲーム全体でのワールド座標を維持することができるようになっています。

例えば、先ほどのParentという親オブジェクトの中に生成したオブジェクトを入れて、ワールド座標を維持させたい場合は、

using UnityEngine;

public class InstantiateManager : MonoBehaviour
{
    public GameObject player;   // publicを付けて変数を宣言する
    public Transform parent;    // 親オブジェクト用にTransform型の変数を宣言する

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))    // スペースキーを押した瞬間
        {
            Instantiate(player, parent ,true);    // parentを親としてワールド座標座標を維持したplayerを生成する
        }
    }
}

という形で書くことで、ワールド座標を維持してオブジェクトが生成されます。

Instantiate(Object, Vector3, Quaternion);

第二引数としてVector3型、第三引数としてQuaternion型を設定してあげることで、生成したいオブジェクトの座標回転量を決めることができます。

Instantiate(生成したいオブジェクト, 生成する座標, オブジェクトの回転量);

座標や回転量を指定しない場合は、生成したい元のオブジェクトの座標と回転量のままになりますが、これを変更したい場合に、引数に指定していきます。

例えば、生成する座標の位置を(2, 2, 0)にして、回転量をそのままにする場合、

using UnityEngine;

public class InstantiateManager : MonoBehaviour
{
    public GameObject player;   // publicを付けて変数を宣言する

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))    // スペースキーを押した瞬間
        {
            Instantiate(player, new Vector3(2, 2, 0), Quaternion.identity);    // (2, 2, 0)の座標に回転量はそのままplayerを生成する
        }
    }
}

と、スクリプトで書いてあげることで、座標の位置を決めて生成することができます。

Instantiate(Object, Vector3, Quaternion, Transform);

先ほどの生成する座標の位置と回転量を指定して、そのオブジェクトを親オブジェクトの中に入れたい場合に、第四引数としてTransform型で親オブジェクトを設定することができます。

Instantiate(生成したいオブジェクト, 生成する座標, オブジェクトの回転量, 親オブジェクト);

使い方は、Instantiate(Object, Transform);と同じで、Parentという親オブジェクトの中にオブジェクトを生成したい場合は、

using UnityEngine;

public class InstantiateManager : MonoBehaviour
{
    public GameObject player;   // publicを付けて変数を宣言する
    public Transform parent;    // 親オブジェクト用の変数を宣言する

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))    // スペースキーを押した瞬間
        {
            Instantiate(player, new Vector3(2, 2, 0), Quaternion.identity, parent);    // (2, 2, 0)の座標に回転量はそのまま親の中にplayerを生成する
        }
    }
}

と書いてアウトレット接続してあげれば、親オブジェクト内で指定した座標と回転量でオブジェクトが生成されます。

Instantiate関数の注意点

ここからは、Instantiate関数を使う際の注意点を紹介していきます。

生成されたオブジェクトはCloneで表記される

Instantiate関数を使ってみると分かりますが、生成されるオブジェクトは元のオブジェクト名の後ろに(Clone)という表記が書かれています。

生成されたオブジェクトということが分かりやすいということもありますが、他のスクリプトでオブジェクト名で参照している場合は、異なることになるため注意が必要です。

なお、この(Clone)表記を消してオブジェクトを生成することもできますので、そちらについては以下の記事で解説していきます。

処理の負荷が重い・大きい

Instantiate関数のようにオブジェクトを新しく生成する処理というのは、実はゲーム内での負荷が大きくゲームパフォーマンスに影響することがあります。

ある程度小規模なゲームであれば影響はあまりないですが、多少大きめのゲームになってくると、Instantiate関数を多用すると重たくなってしまいます。

そこで、ゲームパフォーマンスに影響が出来るだけしないように、Instantiate関数ではなくObjectPoolという機能が使われることがあります。

ObjectPoolは、オブジェクトの生成や消去などの処理を減らすための仕組みになっています。

そのため、Instantiate関数を使っていて、ゲームが少し重たいような場合はObjectPoolの機能を検討しましょう。

まとめ

このページでは、Unityでよく使われるInstantiate関数について、どんな機能や仕組みがあるのか、また使い方までを紹介していきましたが、いかがでしたでしょうか?

Instantiate関数は、簡単にいえばオブジェクトを新しく生成させるためのメソッドとなっています。

引数にオブジェクトを指定してあげることで、そのオブジェクトが生成されるという仕組みになっています。

ゲーム作りの様々な箇所で、Instantiate関数は使うことになると思うので、使い方を覚えておくと良いでしょう。

最後までお読みいただきまして、ありがとうございました!

コメント