I’ve read a bunch of tutorials on implementing finite state machines in Unity, but none of them seem to implement FSM states themselves as Components.
Is there a reason for this that people are aware of?
I would imagine it would be easy to use OnEnable() and OnDisable() to set up and tear down state, you have access to all the normal callback functions, and and enable/disable components needed for that state with SetEnabled().
you cannot call onenable/disable by yourself as this is limited to unitys internals. also the enable/disable refers to the gameobject the component is attached to, not the component itself. at least when i’m not mistaken.
hint: i prefer to define all monobehavior methods as private (fe private void Update). unity is still able to call them as it uses reflection and you cannot accidentially call them AND they do not clutter intellisense.
Oh shoot you’re totally right. Also re-reading the docs it seems to say that any methods within an inactive/disabled component can still be called, the only difference being Update() won’t be called. I guess that’s useful but prone to errors as you point out. Hmm maybe MonoBehaviours isn’t such a great idea…
No, components as states works fine. I’ve used this method before. You can enable and disable components by setting their enabled property. You can activate/deactivate entire GameObjects by calling SetActive().
There are a couple nice things about components as states:
You can see what’s going on in the inspector. The active component is the active state. If the state’s properties are public or serialized, you can see them at a glance in the inspector.
You can build FSMs visually by simply adding the state components you want. I did this for a high level character controller in a project. On some characters, I added all of the states: walk, crouch, climb, swim, etc. On other NPCs, I only added a subset. This customized the NPCs’ capabilities.
One disadvantage is what exiguous points out: You could unintentionally call a public method on a disabled component. If you only rely on Update(), however, you’re safe. You could also add a check to your public methods to immediately exit if the component is disabled.
Another disadvantage is that it tends to make a heavier game object. That might not be an issue for you, though, so your idea is at least worth consideration. It worked great in my specific situation.
I also highly recommend PlayMaker. Not affiliated with them, just a happy customer.
They have a visual FSM editor that makes it real easy to see the transitions between states. Once I learned how to make custom actions, throwing together an FSM became super easy.
+1 for PlayMaker. If you’re not in a hurry, you could even wait for a sale. PlayMaker is very popular, so it’s frequently included in Asset Store Madness sales.