Skip to content

Movement states

Mikhail Albershtein edited this page Apr 4, 2020 · 15 revisions

Movement state

Movement is the most important part of Erbium. I used state design pattern so it's much easier to control the current movement and to switch between them.

The character has a movement component, which is changing constantly depending on the logic you want to implement(the character is falling? then he should be in a falling state, etc..).

The main principle of the state component is that the parent class(Character) is not in charge of changing the movement state. The change is coming from other sources(inputs, physic state, entering the trigger, etc...). It's really important not touching movement in the character class. Try to change the state changeMovement(MovementEnum movement) in state-related classes.

IMovement is the main interface for every movement class. Every movement should implement this interface. Let's discuss its methods.


Lifecycle

Every movement has 3 stages of the life cycle to make it easier to set attributes(set animations, rigidbody attributes, change camera, etc...) inside every state and then set them to default ones.

Set up

void setUp()
Set the attributes you need for this state. Usually, here you should put animation bools, rigidbody attributes, character attributes, etc.. for this specific state.
Typical cases:

  • Disabling gravity, adding gravity scale
  • Set animation bools - onGround, falling
  • Disabling components
  • Changing camera perspective
  • etc..

Move

void move(Vector3 direction)
The main move method which is called every fixed update tick. It doesn't have a lot of mystery, takes the``Vector3 Direction` and moves the character as you want.
Important: don't use any input/camera related stuff here. You should pass the direction where you want your character to move, so the direction should be calculated in a different class(ICameraDirection for the player).
Don't forget to add rotation and update animator attributes if you need to do it every frame.

Change movement

changeMovement(MovementEnum movement)
Changes movement state. You should use this method only in classes that implement IMovement

Clean up

void cleanUp()
Before changing the movement state we need to set all attributes that were set in the Set Up cycle to the default values.

Example

Let's see the flow of a falling change state. Let's imagine that the character is walking off the cliff and starts falling. We have to check every frame if the player is on the ground. If he is not then we have to change the state to midairMovement. But it's important to remember to call the cleanup and setup methods. That's why we invoke changeMovement in the ICharacter class.

Falling flow


AbstractMovement

There is an abstract class with a basic constructor to get values from the characters and a rotation method which you can override. For your movement class try to extend this class if it goes well with the class you want to create.


Movement Enum

In the standard definition of state design patterns, when we change the state, we create a new one. It's not a problem in a normal app, but it's a big problem in Unity because of the garbage collector. The solution is to initialize all of the movements and put them in a dictionary so later we can get them by a key, which is an enum. There is another problem with that because of a dictionary with an enum as a key produces a lot of garbage as well, that's why I had to implement a custom enum comparator. You can find more on this topic here

When you are creating a new movement class, don't forget to initialize it in a start/awake method of a character class, create an enum, and put that into a movement dictionary of the character.


Resumen: Creating your own movement class

To create your movement class you should follow the next steps:

  1. Create a class inside character\movement folder
  2. Extend AbstractMovement or implement IMovement
  3. Override methods that you need
  4. Create an instance of that class in the character start/awake method
  5. Add new movement name to the MovementEnum
  6. Put new movement to the dictionary

That's pretty much it, be careful when you change the state!