Enums & switch
Keywordsenum, switch, case, [Flags]
CategoryTypes & control flow
In UnityKeyCode, ForceMode, Space, LoopType, AI states

Enums & switch

An enum is a type with a fixed list of named options, like Easy, Normal, Hard. It's safer and clearer than using numbers or strings for choices. In the Inspector, enums appear as a dropdown.

A restaurant menu with numbered dishes. You could shout "number 3!", but it's clearer to say "Pizza". An enum gives names to numbers, and the kitchen (the compiler) rejects anything that isn't on the menu.

Declaring and using

public enum Difficulty { Easy, Normal, Hard }   // 0, 1, 2 behind the scenes

public class GameSettings : MonoBehaviour
{
    [SerializeField] private Difficulty difficulty = Difficulty.Normal; // a dropdown in the Inspector

    public float DamageMultiplier()
    {
        if (difficulty == Difficulty.Easy) return 0.5f;
        if (difficulty == Difficulty.Hard) return 1.5f;
        return 1f;
    }
}

switch statements

public enum EnemyState { Patrol, Chase, Attack, Flee }
private EnemyState state;

void Update()
{
    switch (state)
    {
        case EnemyState.Patrol:
            Patrol();
            if (CanSeePlayer()) state = EnemyState.Chase;
            break;                        // every case needs break (or return)

        case EnemyState.Chase:
            MoveToPlayer();
            if (InAttackRange()) state = EnemyState.Attack;
            break;

        case EnemyState.Attack:
            Attack();
            break;

        case EnemyState.Flee:
        default:                          // several labels can share code
            RunAway();
            break;
    }
}

switch expressions (short form)

When each case just produces a value:

float multiplier = difficulty switch
{
    Difficulty.Easy => 0.5f,
    Difficulty.Hard => 1.5f,
    _               => 1f,   // _ means "anything else"
};

Color StateColor(EnemyState s) => s switch
{
    EnemyState.Patrol => Color.green,
    EnemyState.Chase  => Color.yellow,
    EnemyState.Attack => Color.red,
    _                 => Color.gray,
};

Converting enums

int n = (int)Difficulty.Hard;                    // 2
Difficulty d = (Difficulty)1;                    // Normal
string s = Difficulty.Hard.ToString();           // "Hard"
bool ok = System.Enum.TryParse("Easy", out Difficulty parsed); // string -> enum

// Loop over all values
foreach (Difficulty level in System.Enum.GetValues(typeof(Difficulty)))
    Debug.Log(level);

// Save to PlayerPrefs as an int
PlayerPrefs.SetInt("Difficulty", (int)difficulty);

[Flags]: several options at once

Give each option its own bit (1, 2, 4, 8...) and you can combine them. Unity shows flag enums as a multi-select dropdown.

[System.Flags]
public enum DamageType
{
    None   = 0,
    Fire   = 1 << 0,  // 1
    Ice    = 1 << 1,  // 2
    Poison = 1 << 2,  // 4
}

[SerializeField] private DamageType immuneTo = DamageType.Fire | DamageType.Poison; // combine with |

bool IsImmune(DamageType type) => (immuneTo & type) != 0; // check with &
// or: immuneTo.HasFlag(type)

Layer masks work the same way: 1 << 8 is "layer 8".

What happens at runtime

  1. An enum is just an int with names. Comparing and switching on enums is as fast as on numbers.
  2. Unity saves enum fields in scenes/prefabs as their number.
  3. ToString() and Enum.Parse use reflection and allocate a string, so avoid them in Update.

Common Mistakes

See also