Menu
CoddyTech

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 のように一覧表示します。

challenge icon

チャレンジ

簡単

ドアが複数のキーカードを必要とし、キーリングが複数のカードを保持できるようにします。

  1. KeyRing.csで、Accessの上に[System.Flags]を置き、値をNone = 0, Red = 1, Blue = 2, Green = 4にします。
  2. Add(Access card)はすでに保持しているカードを残します:cards |= card;。
  3. 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プレイグラウンド