GetComponents
CoddyのUnityジャーニー「Unityのゲームアーキテクチャ」セクションの一部。レッスン 9/64。
GetComponent<T>()は最初に一致したものを返します。GetComponents<T>()はオブジェクト上で一致したものすべてを配列として返し、GetComponentsInChildren<T>()はオブジェクト上とその下にあるものすべてから一致したものを返します。Tにインターフェースを指定すると、クラスに関係なく、何らかの処理を実行できるパーツを1回の呼び出しですべて集められます。ここでは、工場の機械はFactoryオブジェクトの子であり、電力で動作する各パーツはIPoweredを実装しています。
public interface IPowered
{
void SetPower(bool on);
}public class Generator : MonoBehaviour
{
public GameObject factory;
public void Switch(bool on)
{
IPowered[] parts = factory.GetComponentsInChildren<IPowered>();
foreach (IPowered part in parts)
{
part.SetPower(on);
}
Debug.Log(parts.Length + " parts powered");
}
}LampはLightを切り替え、Fanは回転を始め、Conveyorは動き始めます。それぞれの動作は各自のSetPowerで行います。1つのオブジェクトにLampとFanが付いた機械は、各コンポーネントが別々に一致するため、2つとして数えられます。Generatorはそれらの名前を指定しないため、後からFactoryの下に追加したIPoweredを実装するSirenも、次のSwitchで切り替わります。
GetComponentsInChildrenは呼び出し元のオブジェクトも対象に含み、trueを渡さない限り、非アクティブな子は対象から除外します。例:GetComponentsInChildren<IPowered>(true)。GetComponentsはそのオブジェクト1つだけを調べます。これは、1つのドアに付いたライトとブザーのように、横に並んだパーツに適しています。
チャレンジ
簡単ロボットのすべてのパーツが、攻撃を受けたことを示すようにしましょう。
IHitReaction.csで、public interface IHitReactionとvoid React(int damage);を宣言します。Flash、Recoil、Sparksにこのインターフェースを実装させます。それぞれのメソッド名をpublic void React(int damage)に変更します。- Recoilは
0.5f * damageだけ後ろに移動し、Sparksはdamage個の火花を飛ばします。 TakeDamage内で、すべてのGetComponentsInChildren<IHitReaction>()に対してReact(amount)を呼び出し、その後、個数であるReactions: 3をログに出力します。
「プレイ」を押し、Spaceキーを押してからクリックします。その後、「確認」を押します。
自分で試してみよう
using UnityEngine;
public class Health : MonoBehaviour
{
public int hp = 10;
public void TakeDamage(int amount)
{
hp -= amount;
GetComponentInChildren<Flash>().Show();
}
}
Unityのゲームアーキテクチャのすべてのレッスン
自分で練習してみよう: Unityプレイグラウンド