Skip to content

A Simple Finite State Machine for Unity game objects.

License

MIT, Unknown licenses found

Licenses found

MIT
LICENSE
Unknown
LICENSE.meta
Notifications You must be signed in to change notification settings

saltatory/unity-fsm

Repository files navigation

Simple Unity FSM

Feel free to examine, comment, decry, and use to your heart's content.

Overview

Write a script for a game object that inherits from StateMachine rather than MonoBehaviour.

public class Thingy : StateMachine
{
}

Construct a graph of states.

public class Thingy : StateMachine
{
	// Set of FSM states used in this object
	private State stateFree ;
	private State stateCaptured ;
	private State stateFlushed ;

	void Start () {
		// Create some states
		stateFree = AddState ("Free");
		stateCaptured = AddState ("Captured");
		stateFlushed = AddState ("Flushed");

		// Link the states together
		StartState.AddTransition (stateFree).AddTransition (stateCaptured).AddTransition (stateFlushed);

		// Transition to your initial state
		Transition (stateFree);
	}
}

Handle Transitions

	public override void OnTransition(State from, State to) {
		switch(to.Name){
		case "Free":
			acceptInput = true;
			break;
		// ...
		}
	}

Register other objects to listen for transition events

	private void TransitionedEventHandler(object sender, TransitionArgs args){
		// Stuff that happens over here when a Thingy transitions.
	}

	void SpawnThingys() {
		GameObject spawn = GameObject.Find ("Spawn");

		for (int i=0; i<NumberOfBalls; ++i) {
			GameObject thingy = Instantiate<GameObject>(Resources.Load<GameObject>("Thingy"));
			thingy.transform.position = spawn.transform.position - new Vector3(0,0,5);
			thingy.GetComponent<Thingy>().Transitioned += this.TransitionedEventHandler;
		}
	}

Profit.

Motivation

In working on a 2D game project in Unity, I ran into a problem. I had game objects that would behave differently depending on what had happened to them. The game is a 2D game involving 2D physics and Balls on a tilting table. When the Ball gets captured by a hole, the Ball falls in. While that is happening, the physics change and a series of animations and sounds are played.

Handling the different states of the game objects called for a State Machine.

Unity is awesome as is the Mecanim animation system. I considered using the Mecanim animation system built into Unity. However, I didn't like the fact that the State Machine in that system is a Component attached to a GameObject rather than something that a GameObject could "be". Transitioning between states in the Mecanim system required setting values/triggers on the Animator, requiring that the GameObject knew about all the states. However, the states were setup in the editor. This isn't required but to get the power of the Editor, this is how the tutorials do it. Using the states in the GameObject also required that the GameObject know about the states even though they are created in the Editor. To my way of thinking, this was a weird back-and-forth of dependencies.

A much better design for that system would be if a GameObject could "be" a State Machine and the Mecanim system and the GameObject were both free to use the states and transitions. The Mecanim system would control rendering. The GameObject might control other game-related features like score keeping, object life-cycle, enabled-disabled collision boxes, etc.

Because my game is a relatively simple 2D and the Animations are simple too, it made more sense to handle states right on my GameObjects. Thus this class. The class was inspired by this post. Differences :

  • No reference to a player or NPC. More generic
  • Adds an event handler for non-inheritor objects to be notified
  • No Ids used. State and Transition objects are currently stored in a Set. I saw no compelling reason to include Ids unless they were GameObject InstanceIDs but I also did not want to have to implement MonoBehaviour functions on states and transitions.

Future Work

I implemented a minimum of methods for my own use. There could be more interesting use cases :

  • BeforeTransition()
  • AfterTransition()
  • Some sort of decision system that takes arguments and determines if the transition should happen.

About

A Simple Finite State Machine for Unity game objects.

Resources

License

MIT, Unknown licenses found

Licenses found

MIT
LICENSE
Unknown
LICENSE.meta

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages