Enums & switch
| Keywords | enum, switch, case, [Flags] |
|---|---|
| Category | Types & control flow |
| In Unity | KeyCode, 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
- An enum is just an
intwith names. Comparing and switching on enums is as fast as on numbers. - Unity saves enum fields in scenes/prefabs as their number.
ToString()andEnum.Parseuse reflection and allocate a string, so avoid them inUpdate.
Common Mistakes
- Inserting a new value in the middle (
Easy, Medium, Normal, Hard). Saved Inspector values are numbers, so everything set to "Normal" (1) silently becomes "Medium". Add new values at the end, or give values explicit numbers (Hard = 2). - Forgetting
breakin a switch case: compile error CS0163. - No
default. If you add a new enum value later, a switch without a default silently does nothing for it. Adefaultthat logs a warning helps catch it. - Using strings for states (
state == "chasing"). Typos compile fine. Use an enum.
See also
- Better Ways to Do Things (state machines)
- Types & Type Checking (switch on type)
This page is a simplified, AI-assisted interpretation. For the complete and authoritative reference, see the official Microsoft C# documentation.