I’m following a Youtube tutorial online on how to make a Finite State Machine at the moment and I was hoping someone could help me with something that I don’t understand quite well?
The link to the tutorial is shown here:
The state machine in the tutorial consists of four scripts:
Player.cs
PlayerState.cs
PlayerStateMachine.cs
PlayerData.cs
In the PlayerState script(which does not inherit from MonoBehaviour) he creates three handlers to the other classes by writing the following:
protected Player player;
protected PlayerStateMachine;
protected PlayerData;
Then he has four functions underneath these handlers:
public virtual void Enter(){
}
public virtual void Exit(){
}
public virtual void LogicUpdate(){
}
public virtual void PhysicsUpdate(){
}
public void DoChecks(){
}
In the PlayerStateMachine class he creates a handler to the PlayerState class and creates two functions that deal with the initialization of states and the changing of states respectively like so:
I’m just wondering is the reason why he creates an instance fo the PlayerStateMachine class within the Player class is because he needs to do so in order to get access to the Initialize() and changeState() functions? I’m finding it difficult to understand why he’s creating an instance…
I have not done the tutorial and just looking at your question in general terms. I am assuming Player is a MonoBehavior. Sometimes in object based programming you will hear the terms “is a” and has a" as far as a relationship between classes. “Is a” is inheritance. “Has a” means you create one as part of your object, usually because it isn’t a defining characteristic, but more of an attribute or something you use. Another reason is that sometimes the inheritance is forced, like in the components in Unity.
You could use interfaces, but then there wouldn’t be common code between different components (other MonoBehavior derived classes). You probably could also do this by deriving a state machine class from MonoBehavior and then deriving Player from that, though I don’t know if Unity supports that or not (logically, it should).
A lot of implementations (most, really) are chosen from alternatives. This is the way that made sense to the author.
Another part of the answer is that an instance has to exist for each Player, so the Player should create one. An instance of the Player gets created implicitly because you attached the script to a component. The creation of an object within your script has to be done explicitly.
He actually starts making the state machine at the 1 minute mark. He finishes making the machine by the 10 minute mark approximately.
So basically he creates four scripts:
Player
PlayerState
PlayerStateMachine(which contains two functions related to Initializing and Changing states)
PlayerData
The Player script extends MonoBehaviour and is added as a component on the Player game object in the scene. The PlayerState class acts as a base class. Any state that is created will inherit from the PlayerState class.
He then says that all of the state objects will be created in the Player script. The PlayerStateMachine script contains a reference to the current state.
I’m just wondering is the sole reason for creating an instance of the PlayerStateMachine class is so that he can get access to them in the Player class that is attached to the Player game object in the scene? I’m just trying to wrap my head around to significance of creating an instance of PlayerStateMachine in this context…
I was hoping someone who works with these a lot would speak up. I do not see a technical reason that requires creation of the objects or existence of the class. It just complicates Player if you don’t create another class for handling state. So I think the answer to your original question is yes - it is created so the 2 functions can be called. It is also essentially a variable with the current state (its only public property). It’s also easier to learn about state machines if the classes being created/discussed are purely about state handling. Someone with specific experience may correct my interpretation, but I think you are looking at code hygiene, not a technical requirement.