Перечисления в Inspector
Часть раздела Архитектура игр в Unity путешествия по Unity на Coddy. Урок 17 из 50.
Поле enum отображается в 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 }, все числа сдвинутся, и все предметы подбора во всех сценах изменят тип. Переименовывать значение безопасно, поскольку его число останется прежним. Если явно записать числа, Coin = 0, Heart = 1, Shield = 2, имена можно будет позже переставлять, не меняя ни одного сохранённого выбора.
Перечисление [System.Flags] может хранить сразу несколько значений. В его раскрывающемся списке для каждого значения есть флажок, а также пункты «Ничего» и «Всё». Каждому значению нужен отдельный бит, поэтому используются степени двойки:
[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.
Задание
ЛегкоНа базе есть три двери: для кладовой нужна красная карта-ключ, для лаборатории — синяя, а для хранилища — обе. Значения needs для каждой двери и card для каждой карты задаются в Inspector с помощью перечисления Access, а файлы Door.cs и Keycard.cs уже готовы. Стрелки управляют персонажем Player, у которого в KeyRing хранятся подобранные карты. Заверши KeyRing.cs:
- Сделай
Accessперечислением, значения которого можно комбинировать, чтобы двери могли требовать несколько карт, а кольцо могло хранить несколько карт. Сохрани все четыре имени: None, Red, Blue и Green. Add(Access card)добавляет карту в кольцо, сохраняя уже имеющиеся карты.Opens(Access needs)возвращает true, если в кольце есть все карты, указанные вneeds.
Нажми Play, проверь двери, подбери карты, затем нажми Check.
Попробуйте сами
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Сериализованные данные
Сериализуемые классыСписки в InspectorПеречисления в InspectorПовторение: таблица лута2Интерфейсы в Unity
IDamageableИнтерфейсы и TryGetComponentGetComponentsПовторение: клавиша взаимодействия5ScriptableObjects
Ресурсы данныхХарактеристики оружияОбщие настройкиВолны как данныеПовторение: база предметов