Genshin Impact Movement in Unity | #4 - Creating the Movement State Machine

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
With our abstract class done, we can now create our Player Movement State Machine. This State Machine will of course take  care of all of the Player Movement States. To create it, in Unity, go back to the "Scripts"  folder and create a new folder named "Characters". Then, inside, create another one named "Player". Inside of that "Player" folder, we'll have  yet another folder named "StateMachines", followed by another folder named "Movement". In there, create a new C# Script to which  I'll name "PlayerMovementStateMachine". Open it up and remove the default methods and swap the "MonoBehaviour" inheritance with "StateMachine" instead. This State Machine can now be used to  change between Player Movement States and run their logic. Of course, we don't really have any State  yet as we still need to create them. Before we do that though, lets  first take a look at the differences between Caching States or Instantiating New States. Whenever we call our "ChangeState"  method, we need to pass in our new State. We can do this by either creating a new instance  of the new State Class every time we Change States or create it once and cache that instance in our State Machine. Creating a new instance every time we change  States ensures that if a state isn't being used, resources won't be wasted unnecessarily, as it will be removed. Caching the instance will always have  resources, like memory, being used, as the instance is still needed and won't be automatically removed but, you won't need to  instantiate new States everytime. One thing to note here as well is that creating a new instance always creates the variables again so their values will be reset to their initial default values, while caching the instance will  always have them the way they were. Although, I don't think it  will matter for us too much. Now, which we should use depends in our use case: When a State will be entered quite a lot,  then caching it might be a good idea. Lets take the example of the Player Jumping. It's extremely common for someone to keep pressing  the Jump button while roaming around the map. This means that the Player State will be  changed to the "Jumping State" quite a lot, which makes it a good reason to cache that  State instead of instantiating it every time. Now, lets take an example of  an NPC which has 2 or 3 states that only get changed every 30 minutes. For example, one would be "Idling",  another one would be "Walking" around and another one would be  "Talking" with another NPC. Because they only change every so often,  there isn't much reason to keep them cached and would probably be better for us to  create a new instance at every state change, or, every 30 minutes. This would also make it if there were 100 NPCs in  the map, we wouldn't have 300 States cached in, although we would have 100 States  being instantiated every 30 minutes. Of course, you can mix both usages if you prefer. For our Player however, we'll be caching in all of our States. Now that we know that, lets start by  creating our first Movement States. We'll start with the "Moving States" without the  Group State, but including the "Idling State" and the "Movement State" as well,  as that will be our Base State. So, back in Unity, in the same folder,  create a new folder named "States". Inside, we'll create a new C# Script, to  which I'll name "PlayerMovementState". When that's done, create another folder  named "Grounded", for our "Grounded States". Inside, create a new C# Script  named "PlayerIdlingState". When you're done doing that, create yet another  folder named "Moving", for our "Moving States". Inside, we'll create 3 new C# Scripts:  "PlayerWalkingState", "PlayerRunningState" and "PlayerSprintingState". When you're done creating them, go back 2 folders  and open up the "PlayerMovementState" script. Remove the default methods and swap the "MonoBehaviour" inheritance with an "IState" interface implementation. If you're using an IDE, it should  show an error that says that we should implement the interface methods, so I'll press "Alt + Enter" and implement them. To make it easier for us to know what  State the Player is currently in, we'll log the current state  class name in the "Enter" method. To do that, type in "Debug.Log();" and pass in ""State: " + GetType().Name". This will show the name of the correct Class Type. Other options like "typeof()" or "nameof()"  would always show the parent class name. When that's done, we want to make sure we can override these methods with  their own logic in each state, so we'll need to add the "virtual" keyword  to every single one of the methods. Then, we'll open up all of the  other 4 States we've created and remove their default methods, making sure we swap their inheritance from  "MonoBehaviour" to "PlayerMovementState" as well. We now have our Initial States  so we can start caching them. To do that, head back to the  "PlayerMovementStateMachine" script. Remember that we'll only need to cache in  States that are not considered "Group States". This is because the player will never be  in the "Player Movement State" but instead on the "Idling State" or "Running State", as the "Movement State" simply  exists to group common logic. So, start by typing in "public PlayerIdlingState IdlingState". I'll make it a property with an ommited set. In case you are wondering, here are the differences between writing "private set;"  or simply "omitting" the "set". If you don't want to think about it, simply make it "private" for all properties  that don't use a "public set". Duplicate this property 3 times and swap  their names to be "Walking", "Running" and "Sprinting". We now of course need to instantiate each one  of them, so create a constructor by typing in "public PlayerMovementStateMachine()" and inside simply type in "IdlingState = new PlayerIdlingState();". Do the same thing for all of the other 3 States. Our States are now Cached. That's great, but you have likely  noticed we aren't yet calling any of the State methods in any "MonoBehaviour" class, which means their logic will never  run when we start playing the game. To do that, we need to first  create that "MonoBehaviour" class. So, back in Unity, go all the way back to the "Player" folder and create a new C# Script. I'll name it "Player". Opening it up, remove the default methods. All we need to do now is to create an instance  of our state machine and call its methods. To do that, create a new "private" variable of type "PlayerMovementStateMachine", to which I'll name "movementStateMachine". We now have the "Constructor", "ChangeState", "HandleInput", "Update"  and "PhysicsUpdate" methods to call. We'll call them in the "Awake"  method, the "Start" method, the "Update" method and the "FixedUpdate" method. In the "Awake" method we'll need to create  a new instance of our state machine, so type in "movementStateMachine =  new PlayerMovementStateMachine();". In the "Start" method we need to  define the player starting State. We'll start our Player in the "Idling State". To do that, type in "movementStateMachine.ChangeState();" and pass in "movementStateMachine.IdlingState". Our player should now enter the "Idling  State" whenever the game starts. In the "Update" method we'll need to handle our  input and run our non-physics related logic, so call in "movementStateMachine.HandleInput();"  and "movementStateMachine.Update();". The order is important as we want to make  sure we've got our "Input Data" updated before we do anything with  it in the "Update" method. In the "FixedUpdate" method we'll  need to run our physics related logic, so call in  "movementStateMachine.PhysicsUpdate();". We're now running our current State  logic through our Player Script. Of course, this will never happen unless we  add this script as a component of the Player, so head back into Unity, select the "Player" Game Object and add the "Player" script as a new component. If we now go ahead and enter play mode, a Debug.Log should be called saying that  the player is in the "Idling State".
Info
Channel: Indie Wafflus
Views: 6,871
Rating: undefined out of 5
Keywords: genshin impact movement in unity, genshin impact movement, genshin impact in unity, genshin impact unity tutorial, unity state machines, genshin in unity, genshin movement in unity, genshin gliding in unity, unity 3d movement, unity gliding, unity physics based movement, unity rigidbody movement, unity swimming, unity genshin movement tutorial, unity 3d movement tutorial, unity third person movement, unity genshin impact
Id: qq6Sq8c3LdA
Channel Id: undefined
Length: 10min 51sec (651 seconds)
Published: Fri Feb 25 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.