Menu
CoddyTech

GetComponents

Часть раздела Архитектура игр в Unity путешествия по Unity на Coddy. Урок 9 из 64.

GetComponent<T>() возвращает первое совпадение. GetComponents<T>() возвращает все совпадения на объекте в виде массива, а GetComponentsInChildren<T>() — все совпадения на объекте и во всех его дочерних объектах. Если в качестве T используется интерфейс, один вызов собирает все части, которые могут что-то делать, независимо от их класса. Здесь машины фабрики являются дочерними объектами объекта 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. Машина с Lamp и Fan на одном объекте учитывается дважды, так как каждый компонент — отдельное совпадение. Generator не указывает их имена, поэтому Siren, реализующий IPowered и позднее добавленный под Factory, будет включен при следующем вызове Switch.

GetComponentsInChildren включает объект, на котором его вызывают, и пропускает неактивные дочерние объекты, если не передать true: GetComponentsInChildren<IPowered>(true). GetComponents проверяет только один объект, что подходит для расположенных рядом частей, например лампы и зуммера на одной двери.

challenge icon

Задание

Легко

Пусть каждая часть робота показывает, что по ней попали.

  1. В IHitReaction.cs объяви public interface IHitReaction с void React(int damage);.
  2. Сделай так, чтобы Flash, Recoil и Sparks реализовывали его: переименуй каждый метод в public void React(int damage).
  3. Recoil отодвигает назад на 0.5f * damage; Sparks выпускает damage искр.
  4. В TakeDamage вызови React(amount) для каждого результата GetComponentsInChildren<IHitReaction>(), а затем выведи в журнал Reactions: 3 (их количество).

Нажми «Играть», нажми пробел, затем щёлкни мышью. После этого нажми «Проверить».

Попробуйте сами

using UnityEngine;

public class Health : MonoBehaviour
{
    public int hp = 10;

    public void TakeDamage(int amount)
    {
        hp -= amount;
        GetComponentInChildren<Flash>().Show();
    }
}

Все уроки раздела Архитектура игр в Unity

Потренируйтесь самостоятельно: Песочница Unity