Menu
CoddyTech

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

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

Некоторые вспомогательные методы одинаковы для всех типов: получить компонент или добавить его, выбрать случайный элемент из массива. Обобщённый метод позволяет написать их один раз, указав тип в качестве параметра 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. Если у crate уже есть Rigidbody, метод вернёт его, и ничего не будет добавлено.

У RandomItem нет ограничения, потому что он никак не взаимодействует с T: он работает и с цветами, и со строками, и с префабами. При вызове тип обычно не указывают: по colors, массиву Color[], компилятор определяет, что T — это Color. Метод, который принимает IEnumerable<T> вместо T[], принимает и массивы, и Lists, в том числе массивы, которые возвращает FindObjectsByType<T>.

challenge icon

Задание

Средне

Импульсная башня стоит во дворе. При нажатии Space она посылает импульс: ящики в пределах 4 единиц от неё подбрасывает вверх, а светильники в пределах 4 единиц загораются. Lamp.cs уже готов, в нём есть TurnOn(). Напиши один вспомогательный метод, который находит и те и другие:

  • В Helpers.cs напиши статический класс Helpers с обобщённым методом InRange<T>(IEnumerable<T> items, Vector3 center, float range) для любого типа компонента. Он возвращает List<T> с объектами, расстояние от позиции которых до center не превышает range.
  • В Pulse.cs, когда нажата клавиша Space: каждый Rigidbody в сцене в пределах range от башни получает направленный вверх импульс величиной lift, а каждый Lamp в пределах range включается. Используй InRange для обоих типов объектов в массивах, которые возвращает FindObjectsByType.

Нажми Играть, нажми Space, затем Проверить.

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

using System.Collections.Generic;
using UnityEngine;

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

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

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