Обобщённые вспомогательные методы
Часть раздела Архитектура игр в Unity путешествия по Unity на Coddy. Урок 44 из 64.
Некоторые вспомогательные методы одинаковы для всех типов: получить компонент или добавить его, выбрать случайный элемент из массива. Обобщённый метод позволяет написать их один раз, передавая тип в параметре T, который задаётся при каждом вызове:
public static class Helpers
{
public static T GetOrAdd<T>(this GameObject go) where T : Component
{
if (!go.TryGetComponent(out T found)) found = go.AddComponent<T>();
return found;
}
public static T RandomItem<T>(T[] items)
{
return items[Random.Range(0, items.Length)];
}
}Rigidbody body = crate.GetOrAdd<Rigidbody>();
Color paint = Helpers.RandomItem(colors);
GameObject enemy = Helpers.RandomItem(enemyPrefabs);where T : Component — это требование к T, определяющее, что метод может с ним делать. AddComponent принимает только компоненты, поэтому без этого ограничения компилятор не разрешит go.AddComponent<T>(); с ним подойдёт любой компонент — будь то Rigidbody из Unity или ваши собственные скрипты. Ограничение также даёт доступ ко всем членам Component для T, например к .transform и .gameObject. Если у ящика уже есть Rigidbody, метод вернёт его, и ничего не будет добавлено.
Для RandomItem ограничение не требуется, потому что метод никак не обращается к T: он одинаково хорошо работает с цветами, строками и префабами. Обычно при вызове не нужно указывать тип: по colors — массиву Color[] — компилятор определяет, что T — это Color. Метод, принимающий IEnumerable<T> вместо T[], принимает и массивы, и списки, в том числе массивы, которые возвращает FindObjectsByType<T>.
Задание
СреднеНапиши один универсальный вспомогательный метод для ящиков и ламп башни разрядов.
- В
Helpers.csнапиши статический классHelpersс публичным методомInRange<T>(IEnumerable<T> items, Vector3 center, float range)для компонентов: он должен возвращатьList<T>элементов, находящихся на расстоянии не болееrange. - В
Pulseпри нажатии пробела сообщи каждомуRigidbodyв радиусе действия импульс вверх силойlift. - Затем вызови
TurnOn()для каждой лампы в радиусе действия.
Нажми «Играть» и нажми пробел: ближайший ящик подпрыгнет. Затем нажми «Проверить».
Попробуйте сами
using System.Collections.Generic;
using UnityEngine;
// Helpers.InRange<T>: элементы в пределах заданного расстояния от точки
Все уроки раздела Архитектура игр в Unity
1Компоненты, а не иерархии
Небольшие компонентыБазовый скрипт врагаАбстрактные компонентыКомпоненты работают вместеПовторение: модульная турельПовторение: спаренная пушка4Сериализованные данные
Сериализуемые классыСписки в инспектореПеречисления в инспектореПовторение: таблица добычиПовторение: определяем добычу2Интерфейсы в Unity
IDamageableИнтерфейсы и TryGetComponentGetComponentsПовторение: клавиша взаимодействияПовторение: ближайший в пределах досягаемости5ScriptableObjects
Ресурсы данныхХарактеристики оружияОбщие настройкиСохраняем ветерВолны как данныеПовторение: база предметовПовторение: покупка в магазине8Переиспользуемый код
Методы расширенияОбобщённый синглтонОбобщённые вспомогательные методыПовторение: FindNearestПотренируйтесь самостоятельно: Песочница Unity