Behavioral Design Pattern

State

Armando García Morán

Problem Escenario

Playable Character

Idle

Walk

Jump

class Player
	Update()
		if InputRight 
			moveRight()
			animWalkingRight()
		else if InputLeft
			moveLeft()
			animWalkingLeft()
		else 
			animIdle()

Walk

class Player
    Update()
        if InputRight
            moveRight()
            animWalkingRight()
        else if InputLeft
            moveLeft()
            animWalkingLeft()
        else if InputUp
            moveUp()
            animJumping()
        else
            animIdle()

Jump

Ilimited Jump ?

Constrained Jump

Standing State > Jumping State

Jumping State > Jumping State

class Player
    enum states{ Standing, Jumping }
    currentState = states.Standing;
    Update()
        if InputRight
            moveRight()
            if currentState == states.Standing
                animWalkingRight()
            else animJumping()
        else if InputLeft
            moveLeft()
            if currentState == states.Standing
                animWalkingLeft()
            else animJumping()
        else if InputUp && currentState == states.Standing
            moveUp()
            animJumping()
        else
            animIdle()
    onGroundHit()
        currentState = states.Standing;
    onGroundLeave()
        currentState = states.Jumping;

Jump

class Player
    enum states{ Standing, Jumping, Dead }
    currentState = states.Standing;
    Update()
        if currentState != states.Dead
            if InputRight
                moveRight()
                if currentState == states.Standing
                    animWalkingRight()
                else animJumping()
            else if InputLeft
                moveLeft()
                if currentState == states.Standing
                    animWalkingLeft()
                else animJumping()
            else if InputUp && currentState == states.Standing
                moveUp()
                animJumping()
            else
                animIdle()
    onGroundHit()
        currentState = states.Standing
    onGroundLeave()
        currentState = states.Jumping
    onHit()
        animDead()
        currentState = states.Dead

Dead

class Player
    enum states{ Standing, Jumping, Dead, Crouching }
    currentState = states.Standing;
    Update()
        if currentState != Dead
            if InputRight
                moveRight()
                if currentState == states.Standing
                    animWalkingRight()
                if currentState == states.Crouching
                    animWalkingCrouchedRight()
                else animJumping()
            else if InputLeft
                moveLeft()
                if currentState == states.Standing
                    animWalkingLeft()
                if currentState == states.Crouching
                    animWalkingCrouchedLeft()
                else animJumping()
            else if InputUp &&
                    ( currentState == states.Standing || currentState == states.Crouching )
                moveUp()
                animJumping()
            else if InputDown
                if currentState == states.Standing
                    currentState = states.Crouching                    
                if currentState == states.Standing || currentState == states.Crouching
                    animCrouching()
            else
                animIdle()
    onGroundHit()
        currentState = states.Standing;
    onGroundLeave()
        currentState = states.Jumping;
    onHit()
        currentState = states.Dead;
        

What if I press UP and DOWN at the same time?

This is becoming so messy and we're not even halfway !

State Design Pattern

Allow an object to alter its behavior when its internal state changes. The object will appear to change its class.

Behavior

States

  • Standing
  • Jumping
  • Dead
  • Crouching

Intent

Standing

Dead

Crouching

Jumping

Player

PlayerState

PlayerJumping

PlayerStanding

public interface IPlayerState{
	void Up();
	void Down();
	void Left();
	void Right();
	void UpRight();
	void UpLeft();
	void DownRight();
	void DownLeft();
	void None();
	string GetAnimationName ();
}

PlayerState

PlayerIdle - IdleState

public class PlayerIdle : IPlayerState{
	...
	public static IPlayerState GetInstance(Player player){...}
	public override void Right(){
		player.MoveRight ();
		player.SetState ( PlayerWalking.GetInstance(player) );
	}
	public override void Left(){...}
	public override void Up(){
		player.Jump ();
		player.SetState ( PlayerJumping.GetInstance(player) );
	}
	public override void UpRight(){...}
	public override void UpLeft(){...}
	public override void Down(){
		player.SetState ( PlayerCrouched.GetInstance(player) );
	}
	public override void DownRight(){
		player.MoveRight ();
		player.SetState ( PlayerWalkingCrouched.GetInstance(player) );
	}
	public override void DownLeft(){...}
	public override void None(){}
}
public class Player : MonoBehaviour {
	private IPlayerState currentState ;
	...
	void FixedUpdate () {
		bool up = Input.GetKey (KeyCode.UpArrow);
		bool down = Input.GetKey (KeyCode.DownArrow);
		bool left = Input.GetKey (KeyCode.LeftArrow);
		bool right = Input.GetKey (KeyCode.RightArrow);

		if ( up && !down && !left && !right ) currentState.Up();
		else if ( up && !down && left && !right ) currentState.UpLeft();
		else if ( up && !down && !left && right ) currentState.UpRight();
		else if ( !up && down && !left && !right ) currentState.Down();
		else if ( !up && down && left && !right ) currentState.DownLeft();
		else if ( !up && down && !left && right ) currentState.DownRight();
		else if ( !up && !down && !left && right ) currentState.Right();
		else if ( !up && !down && left && !right ) currentState.Left();
		else currentState.None(); 
	}
	public void SetState(IPlayerState newState){
		if (currentState != newState) {
			currentState = newState;
			...
		}
	}
	void Update(){
		...
			animator.SetTrigger( currentState.GetAnimationName() );
		...
	}
	public void Jump(){...}
	public void MoveRight(){...}
	public void MoveLeft(){...}
	...
}

Player

Can you finish the rest of the states?

State - Design Patterns

By Armando Garcia

State - Design Patterns

  • 595