【Unity】GetComponentsInChildrenで子のコンポーネントを取得できる!

GetComponentsInChildren Unity

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

このページでは、

「GetComponentsInChildrenってなに?」

「子オブジェクトのコンポーネントを取得したい!」

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

Unityで子オブジェクトのコンポーネントを取得する場合に、GetComponentsInChildrenというメソッドが使われます。

このGetComponentsInChildrenは、自分自身および子オブジェクトにアタッチされている指定したコンポーネントを全て取得することができるメソッドです。

GetComponentsInChildrenを使うことで、コンポーネントを検索した順番に配列で取得することができるので、子オブジェクトに一括処理を行うことができるようになります。

そこで、このページでは、UnityのGetComponentsInChildrenというメソッドについて、どんなメソッドなのか、また使い方までをまとめていきます。

この記事を書いた人

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

GetComponentsInChildrenとは?

まずは、GetComponentsInChildrenがどういうメソッドなのか紹介していきます。

子や孫のコンポーネントを検索して一括で取得

GetComponentsInChildrenは、指定したコンポーネントを検索してくれるメソッドで、自分自身もしくは子や孫のオブジェクトに、そのコンポーネントがアタッチされている場合、一括で取得してきてくれるメソッドです。

コンポーネントの検索の順番は、自分自身のオブジェクトから始まり、ヒエラルキーの上から最初の子⇒孫、次の子⇒孫・・・という順番で検索されて取得していきます。

GetComponentsInChildrenで取得されたコンポーネントは、配列を使って受け取ることができるので、すべてのオブジェクトのコンポーネントに一括した処理を行ったり、特定のオブジェクトのコンポーネントにだけ処理を行うといったこともできるようになります。

ちなみに、他にもコンポーネントを取得できるメソッドがいくつかあるので、以下の記事も参考にしてみてください。

自分自身のコンポーネントも取得してくる

GetComponentsInChildrenは、子オブジェクトのコンポーネントを取得してくれるメソッドですが、前述の通り、自分自身のオブジェクトのコンポーネントも取得してしまいます。

そのため、指定したコンポーネントを自身のオブジェクトも持っていた場合、そのコンポーネントの配列に含まれてしまうため、処理を行う際には注意が必要です。

例えば、以下のように四角いオブジェクトを3つ配置して、1つのオブジェクトの配下に2つのオブジェクトを入れて子にしておきます。

この2つの子オブジェクトの色を変更する際に、親のオブジェクトに対して、GetComponentsInChildrenを使ってSpriteRendererコンポーネントを配列で取得して、この配列に対して一括で色の変更処理を行ってみます。

すると、親のオブジェクトにも色の変更処理が行われてしまうことになります。

このように、親オブジェクト(自分自身)も指定したコンポーネントを持っている場合、GetComponentsInChildrenの検索対象となってしまうため注意しておきましょう。

なお、後ほど、親オブジェクトを除外する処理方法を紹介しています。

GetComponentsInChildrenの使い方

ここからは、GetComponentsInChildrenの使い方について紹介していきます。

GetComponentsInChildrenの記述方法

GetComponentsInChildrenを使う際は、以下のように記述することで、コンポーネントを検索して配列で受け取ることができます。

GetComponentsInChildren<コンポーネント名>(includeInactive);

includeInactive:非アクティブのオブジェクトを含めるかどうか(bool型)

GetComponentsInChildrenの後ろに、検索したいコンポーネント名<>の中に記述してあげます。

そして、非アクティブのオブジェクトを含める場合は、引数でbool型の値であるtrueを指定します。

なお、引数を省略した場合は、falseが自動的に入るので、非アクティブのオブジェクトは含まれなくなります。

子のオブジェクトを一括で処理する

実際に、Unity上でGetComponentsInChildrenを使って、子オブジェクトを一括で処理する仕組みを作ってみます。

親を空のオブジェクトとして、その中にRigidbody2Dコンポーネントをアタッチした子オブジェクトを複数配置しておきます。

そして、最初はオブジェクトが落下しないようにRigidbody2DコンポーネントのBodyType「Kinematic」にしておき、スペースキーを押したら「Dynamic」に変わりオブジェクトが落下するようにしていきます。

親となる空のオブジェクトに対して、以下のスクリプトをアタッチしておきます。

using UnityEngine;

public class Test : MonoBehaviour
{
    Rigidbody2D[] rigidbodies;  // Rigidbody2D型の配列を宣言

    void Start()
    {
        rigidbodies = GetComponentsInChildren<Rigidbody2D>();   // コンポーネントを取得する
    }

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            // 配列内のコンポーネントに反復処理
            foreach (Rigidbody2D rb in rigidbodies)
            {
                rb.bodyType = RigidbodyType2D.Dynamic;  // BodyTypeをDynamicに変更する
            }
        }
    }
}

まず、5行目でRigidbody2D型配列を宣言しておきます。

そして、Startの中の9行目でGetComponentsInChildrenを使って、Rigidbody2Dコンポーネントを一括で取得しています。

次に、スペースキーを押した場合の中の17行目から20行目で、foreach文を使ってそれぞれのコンポーネントのBodyTypeDynamicに変更する処理を繰り返しています。

これでゲームを実行してみると、

上記のようにスペースキーを押した際に、子オブジェクトに対して一括した処理を作れているのが分かります。

自分自身を除外して処理を作る

今度は、GetComponentsInChildrenで取得したコンポーネントの中から、自分自身のオブジェクトを除外して処理を作っていきます。

以下のように大きな四角いオブジェクトを親オブジェクト、そして小さな丸いオブジェクトを子オブジェクトとして配置します。

そして、スペースキーを押したら、子オブジェクトの色が一つずつ青色になるという処理を作っていきます。

親オブジェクトに対して、以下のスクリプトをアタッチしておきます。

using UnityEngine;
using System.Collections;

public class Test : MonoBehaviour
{
    SpriteRenderer[] spriteRenderers;  // SpriteRenderer型の配列を宣言

    void Start()
    {
        spriteRenderers = GetComponentsInChildren<SpriteRenderer>();    // SpriteRendererコンポーネントを取得したい
    }

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            StartCoroutine(ColorChange());  // コルーチンをスタート
        }
    }

    IEnumerator ColorChange()
    {
        // 配列内のコンポーネントに反復処理
        foreach (SpriteRenderer rend in spriteRenderers)
        {
            if (rend.gameObject != this.gameObject) // 親オブジェクトを除外する処理
            {
                rend.color = Color.blue;    // 青色に変更する処理
                yield return new WaitForSeconds(0.5f);  // 0.5秒間待つ処理
            }
        }
    }
}

2Dオブジェクトの色変更は、SpriteRendererコンポーネントで行うので、6行目でSpriteRenderer型配列を宣言しています。

そして、Startの中の10行目でGetComponentsInChildrenを使って、コンポーネントの取得を行っています。

また、ここでは、オブジェクトの色を一つずつ変更させたいので、コルーチンの仕組みを使っています。

コルーチンのメソッドとなるColorChangeの28行目で、foreach文の中で青色に変更する処理を繰り返し行っています。

ただし、配列の中に親オブジェクトのSpriteRendererも含まれているため、そのままだと親オブジェクトの色自体も変更されてしまいます。

そこで、26行目で処理しようとしているコンポーネントのオブジェクトが、自分自身のオブジェクトでは無い場合だけ処理されるように記述することで、親オブジェクトへの処理が除外されるようになります。

これでゲームを実行してみると、

親オブジェクトの色は変更されずに、子オブジェクトだけに処理が行われているのが分かります。

まとめ

このページでは、UnityのGetComponentsInChildrenについて、どんなメソッドなのか、また使い方までをまとめていきましたが、いかがでしたでしょうか?

GetComponentsInChildrenは、指定したコンポーネントを自分自身または子や孫の方向に検索して一括で取得してくれるメソッドです。

GetComponentsInChildrenを使うことで、子オブジェクトに対して一括した処理を作ることができるようになります。

ただし、自分自身もコンポーネントの検索対象になるので、処理を作る際は除外対応などを行うようにしましょう。

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

コメント