State Pattern using Unity | raywenderlich.com

Learn all about the Finite State Machine design pattern in Unity. Then implement it to control the movement of your own character!


This is a companion discussion topic for the original entry at https://www.raywenderlich.com/6034380-state-pattern-using-unity

This was great! It really helped me wrap my head around FSM and implementing that with separate classes. One question though. What if we wanted to make the character class a base class also from where we could then inherit character. So Enemy1 and Enemy2 and Player would would inherit character. That way our base class know we need a FSM for them and can be created as such and we can create the individual states for each of the enemies. But if we are using the States abstract class that holds a reference to character, how would we go about calling specific functions on say Enemy1 from the state. Or am I thinking about this wrong? Thanks again for the wonderful tutorial and resources :smiley:

Yes, you can write a base Character class from which you inherit your Player and Enemy types. However, if they behave differently, you would need to have states which are unique to each type.

When you sat states that are unique to to each type, do you mean as in the states that we create that inherit from states, or do I need make a new abstract stateInesertEnemyNameHere class for each enemy type from which I then base the classes for those enemies?

“Making a new state” refers to inheriting the State class and then implementing it of course.

Hey! Thanks for this awesome article!

I implemented my own State Pattern system, with ScriptableObjects. When I see what you did I guess I overengineered this thing a bit :smiley:

A short description to provide context:

  • Context (ScriptableObject) does the same thing as your StateMachine plus stacks previous States, and fires Events OnStateEnter & OnStateExit.
  • States (ScriptableObject) is mostly just a reference to be used by Actions
  • Events (ScriptableObject) to dispatch Enter / Exit to registered Actions
  • Actions (MonoBehaviour) that’s where all the interesting stuff happens:
    • Base Action is abstract and needs to be inherited by real Actions doing things, like go to another State, activate/deactivate gameobjects, play animations, etc.
    • Holds a references to the Context and valid States, and register to Events. So when current State changes on Context and if the new State is valid or not Enter or Exit will be fired.
    • Do whatever it needs to do in Enter, Exit and classic Update.
    • Add it to various gameobjects in the scene.

It leads me to this question how would you implement playing an animation / timeline (or something that takes time) upon Exit?

For instance, let’s say I want to open a door in a certain state and close it when the state is no more valid (or animate a UI element in and out). I would activate an object with a playableDirector attached to it in that particular state and deactivate it otherwise. The opening animation would play nicely because the playableDirector is on an active object, but when the state has changed the object containing the director would be deactivated and it couldn’t run.

To compensate this I added a coroutine that is called before changing state and wait for the animation to finish before actually changing the state. An other idea could be to add intermediary states, but I find it messy and quickly increase the number or states.

It’s a bit off topic but maybe you’ve got a better idea on how to achieve that? I guess that could also apply to your implementation.

Cheers!

I am not sure I completely understand your question but I will try my best to answer.

First off, I don’t think there is a need of coupling the door logic with your state-machine unless you were referring to the state of the door itself.
But, in general to do what you were asking i.e. handling animations at exit, you would need to have some sort of a delay mechanism. How you implement it upto you. The animation could fire an event on completion which you could handle in your current state before making a transition or, like you said you could use a coroutine to provide a fixed time based delay using the length of the animation. There might be other ways as well. Hope that answered you query.

This tutorial is more than six months old so questions are no longer supported at the moment for it. Thank you!