Menu
CoddyTech

GetComponents

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

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");
    }
}

Лампа переключает свой источник света, вентилятор начинает вращаться, а конвейер — двигаться, каждый в своём SetPower. Машина с лампой и вентилятором на одном объекте учитывается дважды, поскольку каждый компонент является отдельным совпадением. Generator никогда не указывает их имена, поэтому сирена, реализующая IPowered и добавленная позднее в качестве дочернего объекта Factory, будет включена при следующем вызове Switch.

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

challenge icon

Задание

Легко

Тренировочный робот должен показывать каждый удар. Health.cs на объекте Robot считает hp, а три части могут реагировать: Flash на объекте Head окрашивает его в красный цвет, Recoil на объекте Robot отбрасывает его назад, а Sparks на объекте Antenna выпускает искры. Пробел наносит роботу 1 единицу урона, а щелчок — 2 (Trainer.cs уже готов). Сейчас Health сообщает только голове.

  • В IHitReaction.cs объяви интерфейс IHitReaction с одним методом: void React(int damage).
  • Сделай так, чтобы Flash, Recoil и Sparks реализовывали этот интерфейс: метод каждого из них должен называться React(int damage). Flash делает то же, что и раньше. Recoil отбрасывает робота назад (+z) на 0.5 единицы за каждую единицу урона, а Sparks выпускает одну искру за каждую единицу урона.
  • В методе TakeDamage класса Health после уменьшения hp вызови React(amount) для каждого IHitReaction на объекте Robot и его дочерних объектах, найденных с помощью одного вызова GetComponentsInChildren, и выведи в журнал количество отреагировавших, например Reactions: 3.

Нажми Play, ударь робота клавишей пробела и щелчком, затем нажми Check.

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

using UnityEngine;

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

    public void TakeDamage(int amount)
    {
        hp -= amount;
        GetComponentInChildren<Flash>().Show();
    }
}
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

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