Semi-amateur Unity dev here, please listen to my insane ramblings and tell me what’s wrong with them. I feel like I’ve been stuck in my head for too long on this question and I need an outside perspective of someone with actual experience. The post isn’t really structured, I’m just writing down my thoughts.
I’ve been stuck figuring out how to best make a good universal state machine for my characters for a while now and I’ve seen quite a few approaches to it, the most basic being a bunch of monobehaviour scripts existing on an entity. But there’s this official open source Unity game about a pig chef that also uses state machines and it basically runs entirely on scriptableobjects - they’re used to store conditions, transitions, states and all of that is eventually stored in a transition table used by a monobehaviour state machine attached to a character. I halfway through to transitioning to that system because it was aimed at better control in the editor, because thanks to all the important pieces being scriptableobjects, you can just plug in whatever conditions and states you want, but what bothers me is that this approach 1) requires you to create an instance of each scriptable object, so you’re basically doubling the number of stuff in your assets folder, 2) creates a whole bunch of scriptableobjects that are only used in one place, which I’m not sure whether that’s an ideal use for them.
In addition to all that, the thing i realized was that states themselves don’t even actually have to be neither monobehaviours, nor scriptableobjects logically speaking - they don’t need to have the Unity callbackslike Update, because you can have custom alternatives that are called in the state machine’s callbacks, so they don’t need to be monobehaviours and they don’t need to be used by multiple objects or store data between launches like scriptableobjects. So theoretically you can build an architecture, where all of the states are just regular C# classes that are created somewhere. But this approach comes with its own peroblems as well, it’ll be harder to use in the inspector, for example.
The next thing is that I need to solve an architectural issue with my simple statemachine, which is that only one state can be active at the same time. This is an issue because there are some values that are shared between states that need to be updated when only one state is active - for example the number of jumps the player has in the air that is shared between an InAir state and an InAirCrouching state. For a while now I’ve been using a simple architecture, where the more specific states like Idle are inherited from broader states like Grounded and the logic from the latter is just reused in the former with the latter never actually being created, it’s just an abstract thing. But I’ve started to think that actually instantiating those higher states and keeping that shared logic in them, updating them separately and then updating the actual child state that is currently in use might be a solution, kind of like a behaviour tree. And I can’t seem to figure out how to do this thing without knowing how to approach the general structure of this whole thing that I talked about above - should i make a whole bunch of scriptableobjects? Make an ugly monobehaviour tree in the scene? Make regular C# classes and put each classes’ children into the constructor though code?
I’m pretty much paralyzed with possibilities. I think I’m stuck with a case of “trying too hard to abstract everything and overcomplicating simple things”. I’d appreciate any help, even if it’s slap to the face and a loud “PLEASE STOP SAYING DUMBASS THINGS, YOU’RE NOT EVEN MAKING SENSE!”.