【Unityゲーム制作入門】オブジェクトの取得の方法を分かりやすく解説

Creating Game

こんにちは。あっきーです。
ゲーム制作をしてプログラミング学習している大学生です。

unity初心者
Unityでオブジェクトの取得をしたいんだけど、どうすればいいんだろう。GameObject.Find使ってもエラーが起こるし…

ということで、今回はオブジェクトの取得について分かりやすく解説していきます。

オブジェクトの取得はかなり良く行うことで、「〇〇したらあるオブジェクトを動かす」のようなことをやる際に必須です。
しっかりマスターしていきましょう。

結論:オブジェクトの取得の方法は3つある

ゲームオブジェクトの取得方法ですが、先にこんなのがあるよという結論を紹介します。

  • public変数にインスペクター上で代入する
  • GameObject.Findを使う
  • transform.Findを使う

以上です。もちろん、細かい分類もあるので、それぞれ特徴と使い方を詳しく説明していきますね。

public変数を用意してインスペクター上で代入する

まず、最も簡単で分かりやすい方法がこちら。

オブジェクトを格納する変数をpublic(公開)にしてインスペクター上で入れてしまう方法です。
変数の公開設定(publicやprivate)については「UnityのC#で使う変数と宣言方法【共有の仕方も教えます】」で解説していますので、参考にどうぞ。


public GameObject gameObject;

このように、宣言すれば、インスペクター上で操作が可能です。取得したいオブジェクトを選択すればOKです。

ここはそこまで複雑ではないので説明は以上です。

GameObect.Findを使う

次はGameObject.Find関数を使った取得方法です。
まずはサンプルのプログラムを作り実行してみます。


using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Sample : MonoBehaviour
{
  private GameObject gameObject;

  void Start()
  {
    //Cube1という名前のオブジェクトを取得
    gameObject = GameObject.Find("Cube1");
  }

  void Update()
  {
    //オブジェクトを点滅させる
    gameObject.SetActive(!gameObject.activeSelf);
  }
}


今、Sampleというスクリプトを用意し、Cube0とCube1というオブジェクトを設置します。
SampleスクリプトはCube0にアタッチしましょう。

この状態で実行すると…

Cube1(右側)が点滅しましたね。Cube1を取得できていることが分かります。

GameObject.Findの使い方

このGameObject.Findの使い方は以下の通りです。

上の例で見ると、「名前」の部分は”Cube1″ですね。()内はstring型(文字列)で入れないといけないので””(ダブルクオーテーション)でくくりましょう。
また()をGetComponentで使う<>と間違えることもしばしばあるので気を付けましょう。

GameObject.Findは全検索できる

このGameObjectの特徴としては、どのオブジェクトでも取得可能です。
transform.Findで出てきますが、親子関係とかそういうのを全く無視して、ヒエラルキー上にあるものすべてが対象になります。

これだけ聞いてもよく分からないと思うので、transfer.Findの部分でもう一度おさらいしましょう。

GameObject.Findを使うときの注意点

GameObject.Findを使うとき、注意点があります。

なるべく1度で取得する

基本的に「オブジェクトを探して取得する」というのはコストが大きいです。
コストが大きいということは、手間がかかるということで、やたらに使いまくると動きが遅くなります。
GameObject.Findは特に、すべてのオブジェクトを対象にしているのでなおさらです。

なのでオブジェクトの取得はできる限り一回で、Startメソッドなどで利用するようにしましょう。

非アクティブのオブジェクトは取得不可

また、この方法だと、非アクティブなオブジェクトは取得できません。
例えば、先ほどのプログラムでCube1の状態を非アクティブにして実行してみてください。

このように「値がありません」というエラーが起こります。
これはよく起こるエラーですので、注意をしてくださいね。

transform.Findを使う

次はtransform.Find関数を利用した方法です。
使い方は先ほどのGameObject.Findと一緒です。
transform.Find("オブジェクト名")で取得ができます

transform.Findの特徴

ただ特徴に大きな違いがあります。

  • 子オブジェクトのみ取得ができる
  • transform型で返ってくる
  • 対象のオブジェクトが非アクティブでも取得可能

子オブジェクトにのみ適用

transform.Findは子オブジェクトだけを対象としています。
GameObjectはヒエラルキー上の全部が対象だったのでここは大きく違いますね。

「子オブジェクトって何?」という方は、別の記事で、オブジェクトの親子関係について説明しているのでそちらを参考にしてください。(後日公開)

型はtransform型

この方法で取得した場合、型はtransform型になります。
transform型とは位置や回転などの情報を持つコンポーネントです。

つまり、変数で格納するときに


private Transform cube;

のように、transform型で宣言しなければなりません。

「いやいや、GameObject型で扱いたい」という場合(例えば、アクティブ・非アクティブの操作をしたいなど)、


private GameObject cube;

void Start()
{
  cube = transform.Find("Cube").gameObject;
}

のように、後ろに.gameObjectとくっつければ型をGameObject型に変えることができます。

非アクティブのオブジェクトもOK

また、transform.Findであれば非アクティブなオブジェクトでも取得可能です。

実際に例を見てみましょう。先ほどのSampleスクリプトを変更します。


using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Sample : MonoBehaviour
{
  private GameObject cube1;
  private Transform cube2;

  void Start()
  {
    cube1= GameObject.Find("CUbe1");
    cube2 = transform.Find("Cube2");
    Debug.Log(cube1);
    Debug.Log(cube2);
  }
}

cube1はGameObject.Findで、cube2はtransform.Findで取得します。
また、ヒエラルキー上で画像のように、Cube1, Cube2をCubeの子要素として追加しましょう。そしてこの2つを非アクティブにします。

この状態で実行しましょう。

cube1はGameObject.Findで取得していたので、nullという「何もない値」が返ってきました。
一方、cube2はtransform.Findで取得したので、しっかり取得ができていますね。(型もTransformになってます)。

初めから非アクティブにしておきたいオブジェクトを取得する際に便利ですね。

子要素を番号で取り出すGetChild関数

transform.Findは子要素の取得に利用できました。これと似たもので、transform.GetChildという関数もあります。

前者が名前検索なのに対し、後者は番号検索です。
transform.GetChild(n)という形で使うことができます。

nに数字をいれるんですが、子要素を上から順番に「0,1,2…」と割り振って取得したい番号を入れます。

先ほどのプログラムをちょっと変更してみましょう。


using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Sample : MonoBehaviour
{
  private Transform cube2;

  void Start()
  {
    //子要素の2番目を取得
    cube2 = transform.GetChild(1);
    Debug.Log(cube2);
  }
}

Cube2を取得したい場合、子要素の2番目にあるので、0から数えると”1″を使えば良いですね。
(数字が0から始まるところに注意!)

これで実行してみると…

このようにCube2を取得することができていますね。

for文で子要素を複数取得できる

GetChildの利点は番号で子オブジェクトを取得できるところです。
名前だと特定のオブジェクトを取得することはできますが、逆に言うと複数の取得には向いていません。
また、名前を変えたりしたらコードも変更しないといけません(なかなか面倒)。

ですが、GetChildなら順番で決まるため、複数のオブジェクトを取得することもできます。
for文などを利用して配列に格納することで実装できます。

プログラムの例と実行結果だけ記しておきますね。


using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Sample : MonoBehaviour
{
  private Transform[] cube;

  void Start()
  {
    cube = new Transform[2];
    for(int i = 0 ; i < 2 ; i++)
    {
      cube[i] = transform.GetChild(i);
      Debug.Log(cube[i]);
    }
  }
}

まとめ

ということで、今回はGameObjectの取得方法について学びました。
Unityを使う以上必須アイテムなのでしっかりマスターしておきましょう。

それでは、また

<まとめ>

  • GameObject.Find → 全検索, 非アクティブは不可, GameObject型
  • transform.Find → 子要素検索, 非アクティブ可, Transform型

人気記事現役大学生が告白!大学生がブログを始めるのをオススメする理由

人気記事WordPress(ワードプレス)の始め方【初心者でも15分で開設】