Inspectorでの列挙型
CoddyのUnityジャーニー「Unityのゲームアーキテクチャ」セクションの一部。レッスン 20/64。
enum フィールドはインスペクターにドロップダウンとして表示されるため、同じスクリプトを共有するオブジェクトを設定するのに便利です。1つの 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] enum は一度に複数の値を保持します。そのドロップダウンには、各値のチェックボックスと、「なし」「すべて」が表示されます。各値には専用のビットが必要なので、番号には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 です。HasFlag(x) は、x のすべての値が設定されている場合に true になり、ToString() は設定されている値を Fire, Poison のように一覧表示します。
チャレンジ
簡単ドアが複数のキーカードを必要とし、キーリングが複数のカードを保持できるようにします。
KeyRing.csで、Accessの上に[System.Flags]を置き、値をNone = 0, Red = 1, Blue = 2, Green = 4にします。Add(Access card)はすでに保持しているカードを残します:cards |= card;。Opens(Access needs)は、キーリングがneedsに含まれるすべてのカードを保持している場合にのみtrueを返します。
「プレイ」を押して両方のカードを拾うと、Vaultが開きます。その後、「確認」を押します。
自分で試してみよう
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プレイグラウンド