Menu
CoddyTech

Обобщённые вспомогательные методы

Часть раздела Архитектура игр в 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>.

challenge icon

Задание

Средне

Напиши один универсальный вспомогательный метод для ящиков и ламп башни разрядов.

  1. В Helpers.cs напиши статический класс Helpers с публичным методом InRange<T>(IEnumerable<T> items, Vector3 center, float range) для компонентов: он должен возвращать List<T> элементов, находящихся на расстоянии не более range.
  2. В Pulse при нажатии пробела сообщи каждому Rigidbody в радиусе действия импульс вверх силой lift.
  3. Затем вызови TurnOn() для каждой лампы в радиусе действия.

Нажми «Играть» и нажми пробел: ближайший ящик подпрыгнет. Затем нажми «Проверить».

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

using System.Collections.Generic;
using UnityEngine;

// Helpers.InRange<T>: элементы в пределах заданного расстояния от точки

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

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