Перечисления в инспекторе
Часть раздела Архитектура игр в Unity путешествия по Unity на Coddy. Урок 20 из 64.
Поле перечисления отображается в Inspector в виде раскрывающегося списка — это удобный способ настраивать объекты, использующие один скрипт. Один префаб Pickup подходит для монет, сердец и щитов: каждая его копия на уровне получает свой тип из раскрывающегося списка, а скрипт выбирает действие в зависимости от него:
public enum PickupKind { Coin, Heart, Shield }
public class Pickup : MonoBehaviour
{
public PickupKind kind;
public int amount = 1;
void OnTriggerEnter(Collider other)
{
if (!other.TryGetComponent(out PlayerStats stats)) return;
switch (kind)
{
case PickupKind.Coin: stats.coins += amount; break;
case PickupKind.Heart: stats.hp += amount; break;
case PickupKind.Shield: stats.shielded = true; break;
}
Destroy(gameObject);
}
}Сцена сохраняет каждый вариант как числовое значение: Coin — это 0, Heart — 1, Shield — 2. Добавить значение в конец безопасно. Если вставить его в начало, как в { Gem, Coin, Heart, Shield }, все числа сдвинутся, и тип каждого Pickup во всех сценах изменится. Переименовать значение безопасно, поскольку его число останется прежним. Если явно указать числа — Coin = 0, Heart = 1, Shield = 2, — позже можно будет менять порядок названий, не затрагивая сохранённые варианты.
Перечисление [System.Flags] хранит несколько значений одновременно. В его раскрывающемся списке для каждого значения есть флажок, а также пункты Nothing и Everything. Каждому значению нужен собственный бит, поэтому используются степени двойки:
[System.Flags]
public enum Element { None = 0, Fire = 1, Ice = 2, Poison = 4 }
public Element immuneTo; // отмечены в Inspector: Fire и Poison
public void Hit(int damage, Element element)
{
if (immuneTo.HasFlag(element)) return;
hp -= damage;
}| объединяет значения: Element.Fire | Element.Poison равно 5. HasFlag(x) возвращает true, когда установлены все значения из x, а ToString() перечисляет установленные значения, например Fire, Poison.
Задание
ЛегкоПусть двери требуют несколько ключ-карт, а кольцо хранит несколько карт.
- В
KeyRing.csпоставь[System.Flags]надAccessи пронумеруй его так:None = 0, Red = 1, Blue = 2, Green = 4. Add(Access card)сохраняет уже имеющиеся карты:cards |= card;.Opens(Access needs)возвращает true, только когда кольцо хранит каждую карту изneeds.
Нажми «Играть» и подбери обе карты: хранилище откроется. Затем нажми «Проверить».
Попробуйте сами
using UnityEngine;
public enum Access { None, Red, Blue, Green }
public class KeyRing : MonoBehaviour
{
public Access cards;
public void Add(Access card)
{
// добавить карту в связку, сохранив уже имеющиеся карты
}
public bool Opens(Access needs)
{
// true, если в связке есть все карты из needs
return false;
}
}
Все уроки раздела Архитектура игр в Unity
1Компоненты, а не иерархии
Небольшие компонентыБазовый скрипт врагаАбстрактные компонентыКомпоненты работают вместеПовторение: модульная турельПовторение: спаренная пушка4Сериализованные данные
Сериализуемые классыСписки в инспектореПеречисления в инспектореПовторение: таблица добычиПовторение: определяем добычу2Интерфейсы в Unity
IDamageableИнтерфейсы и TryGetComponentGetComponentsПовторение: клавиша взаимодействияПовторение: ближайший в пределах досягаемости5ScriptableObjects
Ресурсы данныхХарактеристики оружияОбщие настройкиСохраняем ветерВолны как данныеПовторение: база предметовПовторение: покупка в магазинеПотренируйтесь самостоятельно: Песочница Unity