检视面板中的枚举
本课属于 Coddy Unity 学习旅程的“Unity 游戏架构”单元。第 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 },会改变每个值对应的数字,导致所有场景中的每个拾取物都改变类型。重命名一个值是安全的,因为它对应的数字不会变。显式写出数字,例如 Coin = 0, Heart = 1, Shield = 2,之后就可以重新排列名称,而不会改变任何已保存的选项。
[System.Flags] 枚举可以同时保存多个值。它的下拉菜单会为每个值显示一个勾选项,另外还有“无”和“全部”。每个值都需要占用独立的一位,因此数字必须是 2 的幂:
[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。当 x 中的所有值都已设置时,HasFlag(x) 会返回 true;ToString() 会列出已设置的值,例如 Fire, Poison。
挑战
简单让一扇门需要多张门卡,并让钥匙圈可以装多张门卡。
- 在
KeyRing.cs中,将[System.Flags]放在Access上方,并将它们编号为None = 0, Red = 1, Blue = 2, Green = 4。 Add(Access card)会保留已有的门卡:cards |= card;。- 只有当钥匙圈里有
needs中的每一张门卡时,Opens(Access needs)才返回 true。
按“开始”并拾取两张门卡,金库就会打开。然后点击“检查”。
亲手试试
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)
{
// 当卡环上有 needs 中的所有卡片时,返回 true
return false;
}
}
Unity 游戏架构中的所有课
自己练习: Unity 在线编辑器