State Machines In Unity

Last Updated : 4 May, 2026

A state machine controls which behavior is active at any time. Only one state runs at a time. When conditions change, the machine switches to a different state.

  • Player standing still - Idle state
  • Player presses arrow - Walk state
  • Player presses space - Jump state
States-In-Unity
States In Unity

Basic State Machine Structure

First, create an enum to list all possible states.

C#
public enum PlayerState
{
    Idle,
    Walk,
    Run,
    Jump,
    Attack
}

Then create a manager script that switches between states.

C#
public class StateMachine : MonoBehaviour
{
    public PlayerState currentState;
    void Start()
    {
        currentState = PlayerState.Idle;
    }
    void Update()
    {
        switch (currentState)
        {
            case PlayerState.Idle:
                Idle();
                break;
            case PlayerState.Walk:
                Walk();
                break;
            case PlayerState.Run:
                Run();
                break;
            case PlayerState.Jump:
                Jump();
                break;
            case PlayerState.Attack:
                Attack();
                break;
        }
    }
    void Idle()
    {
        // Play idle animation
        // Check for input to switch state
        if (Input.GetAxis("Horizontal") != 0)
            currentState = PlayerState.Walk;
        
        if (Input.GetButtonDown("Jump"))
            currentState = PlayerState.Jump;
    }
    void Walk()
    {
        // Move player
        // Play walk animation
        
        if (Input.GetAxis("Horizontal") == 0)
            currentState = PlayerState.Idle;
        
        if (Input.GetButtonDown("Jump"))
            currentState = PlayerState.Jump;
    }
    void Run()
    {
        // Run logic
    }
    void Jump()
    {
        // Jump logic
        // After jump, return to Idle or Walk
    }
    void Attack()
    {
        // Attack logic
    }
}

Output:

State-Machine-Structure-In-Unity
Basic State Machine In Unity

Complete Player State Machine Example

Here's a full working example for a player character

C#
public class PlayerStateMachine : MonoBehaviour
{
    public enum State
    {
        Idle,
        Walking,
        Jumping,
        Attacking
    }
    public State currentState;
    private Rigidbody rb;
    private Animator anim;
    private float moveSpeed = 5f;
    private float jumpForce = 10f;
    private bool isGrounded;
    void Start()
    {
        rb = GetComponent<Rigidbody>();
        anim = GetComponent<Animator>();
        currentState = State.Idle;
    }
    void Update()
    {
        // Check ground (simplified)
        isGrounded = Physics.Raycast(transform.position, Vector3.down, 1.1f);
        
        switch (currentState)
        {
            case State.Idle:
                UpdateIdle();
                break;
            case State.Walking:
                UpdateWalking();
                break;
            case State.Jumping:
                UpdateJumping();
                break;
            case State.Attacking:
                UpdateAttacking();
                break;
        }
    }
    void UpdateIdle()
    {
        anim.Play("Idle");
        float move = Input.GetAxis("Horizontal");
        if (move != 0)
        {
            currentState = State.Walking;
        }
        
        if (Input.GetButtonDown("Jump") && isGrounded)
        {
            currentState = State.Jumping;
        }
        
        if (Input.GetButtonDown("Fire1"))
        {
            currentState = State.Attacking;
        }
    }
    void UpdateWalking()
    {
        float move = Input.GetAxis("Horizontal");
        
        if (move == 0)
        {
            currentState = State.Idle;
        }
        // Move player
        transform.Translate(Vector3.right * move * moveSpeed * Time.deltaTime);
        anim.Play("Walk");
        
        if (Input.GetButtonDown("Jump") && isGrounded)
        {
            currentState = State.Jumping;
        }
        if (Input.GetButtonDown("Fire1"))
        {
            currentState = State.Attacking;
        }
    }
    void UpdateJumping()
    {
        if (isGrounded && rb.velocity.y <= 0)
        {
            currentState = State.Idle;
        }
        
        rb.velocity = new Vector3(rb.velocity.x, jumpForce, rb.velocity.z);
    }
    void UpdateAttacking()
    {
        anim.Play("Attack");
        StartCoroutine(ReturnToIdle());
    }
    IEnumerator ReturnToIdle()
    {
        yield return new WaitForSeconds(0.5f);
        if (currentState == State.Attacking)
        {
            currentState = State.Idle;
        }
    }
}

State Machine with Separate Classes

For complex games, create separate classes for each state.

C#
// Base class for all states
public abstract class State
{
    protected PlayerController player;
    
    public State(PlayerController player)
    {
        this.player = player;
    }
    public abstract void Enter();
    public abstract void Update();
    public abstract void Exit();
}
// Idle state
public class IdleState : State
{
    public IdleState(PlayerController player) : base(player) { }
    
    public override void Enter()
    {
        player.anim.Play("Idle");
    }
    public override void Update()
    {
        if (player.moveInput != 0)
        {
            player.stateMachine.ChangeState(new WalkState(player));
        }
        
        if (player.jumpPressed)
        {
            player.stateMachine.ChangeState(new JumpState(player));
        }
    }
    public override void Exit() { }
}
// Walk state
public class WalkState : State
{
    public WalkState(PlayerController player) : base(player) { }
    public override void Enter()
    {
        player.anim.Play("Walk");
    }
    public override void Update()
    {
        player.Move();
        
        if (player.moveInput == 0)
        {
            player.stateMachine.ChangeState(new IdleState(player));
        }
    }
    public override void Exit() { }
}

And the state machine manager:

C#
public class StateMachine
{
    public State currentState;
    public void ChangeState(State newState)
    {
        currentState?.Exit();
        currentState = newState;
        currentState.Enter();
    }
}
public class PlayerController : MonoBehaviour
{
    public Animator anim;
    public float moveInput;
    public bool jumpPressed;
    public StateMachine stateMachine;
    void Start()
    {
        stateMachine = new StateMachine();
        stateMachine.ChangeState(new IdleState(this));
    }
    void Update()
    {
        moveInput = Input.GetAxis("Horizontal");
        jumpPressed = Input.GetButtonDown("Jump");
        stateMachine.currentState?.Update();
    }
}

When to Use a State Machine

Good for

  • Player behavior (idle, walk, jump, attack).
  • Enemy AI (patrol, chase, attack, flee).
  • Game states (menu, playing, paused, game over).
  • Any system with multiple modes or transitions.

Not needed for

  • Simple moving platforms.
  • Static obstacles.
  • Single-state objects (no behavior change).
  • Very basic scripts with no state switching.
Comment
Article Tags:

Explore