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 проверяет только один объект, что подходит для расположенных рядом частей, например лампы и зуммера на одной двери.
Задание
ЛегкоТренировочный робот должен показывать каждый удар. 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();
}
}
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Архитектура игр в Unity
1Компоненты, а не иерархии
Небольшие компонентыБазовый скрипт врагаАбстрактные компонентыСовместная работа компонентовПовторение: модульная турель4Сериализованные данные
Сериализуемые классыСписки в InspectorПеречисления в InspectorПовторение: таблица лута2Интерфейсы в Unity
IDamageableИнтерфейсы и TryGetComponentGetComponentsПовторение: клавиша взаимодействия5ScriptableObjects
Ресурсы данныхХарактеристики оружияОбщие настройкиВолны как данныеПовторение: база предметов