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 проверяет только один объект, что подходит для расположенных рядом частей, например лампы и зуммера на одной двери.
Задание
ЛегкоПусть каждая часть робота показывает, что по ней попали.
- В
IHitReaction.csобъявиpublic interface IHitReactionсvoid React(int damage);. - Сделай так, чтобы
Flash,RecoilиSparksреализовывали его: переименуй каждый метод вpublic void React(int damage). Recoilотодвигает назад на0.5f * damage;Sparksвыпускаетdamageискр.- В
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
1Компоненты, а не иерархии
Небольшие компонентыБазовый скрипт врагаАбстрактные компонентыКомпоненты работают вместеПовторение: модульная турельПовторение: спаренная пушка4Сериализованные данные
Сериализуемые классыСписки в инспектореПеречисления в инспектореПовторение: таблица добычиПовторение: определяем добычу2Интерфейсы в Unity
IDamageableИнтерфейсы и TryGetComponentGetComponentsПовторение: клавиша взаимодействияПовторение: ближайший в пределах досягаемости5ScriptableObjects
Ресурсы данныхХарактеристики оружияОбщие настройкиСохраняем ветерВолны как данныеПовторение: база предметовПовторение: покупка в магазинеПотренируйтесь самостоятельно: Песочница Unity