A feature from another language i used (LSL specifically) was states. The code could transition into a different state, and it could have a whole new set of eventhandler (or monobehaviours in our case) defined, as well as ceasing to callthe old ones.
It was a feature that didn’t have any necessary uses, but used well it could significantly improve efficiency, readability, and general flow of a program. i liked it.
it’d be nice to define several different Update() functions, for example, and switch states to define their behaviour, rather than using conditionals inside update, which is a little messy, and has a tiny amount of extra overhead.
There’s no syntax in C# to specifically pull this off.
But really these states can just be represented as classes. Then you create instances of the class for the state you’re in currently.
I know ‘unrealscript’ had a very similar feature to what you describe. I’m assuming LSL is the ‘second life’ scripting language, which I bet is similar. And behind the scenes unrealscript really is just creating classes for each state. It’s just syntax sugar hiding all the heavy lifting from you.
I actually do this frequently. I have it abstracted to a container class to contain the states. There are several versions that allow for various types of states (I have a component based one, I have another that allows stacking states, and other stuff).
Then each state just gets placed into this container, and there is a method on it ‘ChangeState’ that takes in either the type of the state to change to, or the actual object that represents the state.
This is the general idea of it:
public class SomeScript
{
private StateMachine<ISomeScriptState> _states;
void Awake()
{
_states.Add(new StateA());
_states.Add(new StateB());
_states.ChangeState<StateA>();
}
void Update()
{
_states.Current.Update();
}
public interface ISomeScriptState
{
void Update();
}
public class StateA : ISomeScriptState
{
public void Update()
{
//do state a stuff
}
}
public class StateB : ISomeScriptState
{
public void Update()
{
//do state b stuff
}
}
}
Another more Unity-specific way of doing it is to attach two (or more) separate monobehaviors to a GameObject, and then have a another monobehavior control which is active, by turning each one on or off.
For instance, you might have a FlyingControls class and a WalkingControls class, and hang them both on the player object.
A third class would simply disable Flying when the player is on the ground, and enable the walking controls, but if the player (for instance) double-jumps, then enable flying and disable walking, simply by keeping a reference to each script instance, and toggling the .enabled field true/false.
Ultimately, there’s nothing really wrong with using Switch Statements for State transitions. However its typically cleaner (especially for Transitioning into and out of a State) to use a Class that manages States and to Isolate state-specific behaviour in Classes (or Classes that implement a State Interface) that the State Manager can use abstractly without knowing the details of a State.
That and data between the States would bloat up quickly where some data is only used in one specific State, but must persist in a scope beyond the local scope of a function. Think of trying to manage persistent data within States in one class, where data might be specific only to one particular State. It would be a lot of information that only belongs to a State, so a Class per State is preferable to store the information in that case since that’s what Classes are used for.
If you need to communicate information between States or abstract commonality between States, then you may want to use a different Design Pattern for that particular case. I haven’t done enough research on HSM’s but I think they fall within the latter category. As for the former, then yes having a Switch Statement might be fine, though I also think that having Substates of a State may be an effective way to communicate between Substates of a given State by using the State as the persistent scope where the Substates can access this data (basically the State becomes a State Manager for the Substates, but the highest-level State Manager still doesn’t know this and doesn’t really need to know how the State acting as a State Manager works).
You could probably communicate between States in a decoupled manner by using Events, but I haven’t given those a good enough read to wholeheartedly recommend.
It really just depends on the Use Case and the problem you’re trying to solve.
The CSharp Messenger Extended seems like a Use Case for the Observer/Observable pattern. I’m pretty sure the question was simply about changing Behaviour logic at runtime depending on the state of something, where a StateMachine/StateManager is a better Design Pattern solution for this problem.