State Pattern Using Unity
Learn all about the Finite State Machine design pattern in Unity. Then implement it to control the movement of your own character! By Najmm Shora.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
State Pattern Using Unity
20 mins
Sneaking Under the Table
Open Ducking.cs. Notice Ducking also inherits from the Grounded class for the same reasons Standing does. Add the following override methods and save the script:
public override void Enter()
{
base.Enter();
character.SetAnimationBool(character.crouchParam, true);
speed = character.CrouchSpeed;
rotationSpeed = character.CrouchRotationSpeed;
character.ColliderSize = character.CrouchColliderHeight;
belowCeiling = false;
}
public override void Exit()
{
base.Exit();
character.SetAnimationBool(character.crouchParam, false);
character.ColliderSize = character.NormalColliderHeight;
}
public override void HandleInput()
{
base.HandleInput();
crouchHeld = Input.GetButton("Fire3");
}
public override void LogicUpdate()
{
base.LogicUpdate();
if (!(crouchHeld || belowCeiling))
{
stateMachine.ChangeState(character.standing);
}
}
public override void PhysicsUpdate()
{
base.PhysicsUpdate();
belowCeiling = character.CheckCollisionOverlap(character.transform.position +
Vector3.up * character.NormalColliderHeight);
}
- Inside
Enter, the parameter to trigger the crouch animation is set to true which enables the crouch animation. Thecharacter.CrouchSpeedandcharacter.CrouchRotationSpeedproperties set thespeedandrotationwhich return the intended translation and angular speed of the character while crouching.
Next,character.CrouchColliderHeightsets the collider size of the character, which returns the intended collider height while crouching. Finally,belowCeilingis reset to false. - Inside
Exit, the parameter for crouch animation is set to false. This would disable the crouch animation. Afterwards the collider height is set to normal intended height returned bycharacter.NormalColliderHeight. - Inside
HandleInput,crouchHeldis set to accept the user input. In the Main scene, holding down Shift will setcrouchHeldto true. - Inside
PhysicsUpdate, thebelowCeilingvariable is set by passing in theVector3point near the Character GameObject’s head toCheckCollisionOverlapby. If there is a collision around that point, it means the Character is below a ceiling of some sort. - Inside
LogicUpdate, you check to see if eithercrouchHeldorbelowCeilingis true. If neither of them is true,movementSM.CurrentStatechanges tocharacter.standing.
Build and click Play. Now you should be able to move around. If you press Shift, the Character will crouch and you can move around while crouching.
You should also be able to go under the platforms. If you release Shift while underneath the platforms, the Character will continue crouching until you leave its cover.

Up, Up and Away!
Open Jumping.cs. You’ll see a method named Jump. Don’t worry about its specifics but understand it’s used to make the Character jump with physics, animation and magic! :]
Now add the usual override methods and save the script
public override void Enter()
{
base.Enter();
SoundManager.Instance.PlaySound(SoundManager.Instance.jumpSounds);
grounded = false;
Jump();
}
public override void LogicUpdate()
{
base.LogicUpdate();
if (grounded)
{
character.TriggerAnimation(landParam);
SoundManager.Instance.PlaySound(SoundManager.Instance.landing);
stateMachine.ChangeState(character.standing);
}
}
public override void PhysicsUpdate()
{
base.PhysicsUpdate();
grounded = character.CheckCollisionOverlap(character.transform.position);
}
- Inside
Enter, theSoundManagersingleton plays the jump sound. Afterwards,groundedis reset to its default value. FinallyJumpgets called. - Inside
PhysicsUpdate, theVector3point near the Character’s feet is sent toCheckCollisionOverlap, which meansgroundedwill be set to true if the Character is on ground. - In
LogicUpdatewhengroundedis true, you callTriggerAnimationfor the landing animation, a landing audio plays andmovementSM.CurrentStatechanges tocharacter.standing.
Finally, with this, you’ve fully implemented the movement FSM using the State Pattern. Build and play. Use Space to make the character jump.

Now you can say, “my code is in a state!” with a smile on your face! :]
Where to Go From Here?
You can use the Download Materials button at the top and bottom of this tutorial to download both the starter and final projects.
While state machines are useful they come with their own limitations. Concurrent State Machines and Pushdown Automata tackle some of those limitations. You can read more about them in the book Game Programming Patterns by R.Nystrom.
You can also delve deeper by exploring behavioral trees for making advanced in-game entities.
I hope you found this tutorial useful and enjoyed learning the topic. Please feel free to join the forum below for any questions or comments.