Skip to content

Character Controller

Game Creator Characters have been build to be easy to use and highly customizable. This section go over what a Character does every frame cycle. This will put you in perspective in order to create a custom Character that works with Game Creator or you want to integrate a Character system from another package into Game Creator.

The Character component is composed of 5 different Units which conform the Kernel. These units can be changed at runtime without affecting the rest:

  • Player: Defines whether the Character is a playable one and how the user can interact with it. If you want to create a custom Character input system, you'll need to implements the ICharacterPlayer interface.
  • Motion: Acts as an interface between the scene and the Character. All movement commands are relayed through this system and also takes into account the Player's information. It decides which locomotion system should be used. If you want to create a different motion system for your characters, create a class that implements the ICharacterMotion interface.
  • Driver: Manages how the Character moves around the scene based on the Motion's input. If you want to integrate another Character system from another Asset Store package, create a new class that implements from ICharacterDriver.
  • Facing: Is responsible for rotating the character towards a desired direction. For example, the default behavior is to have the character look towards where it's moving. If you want to customize where the character faces, create a custom class that implements the ICharacterFacing interface.
  • Animim: This system takes the Driver's input and tells the Animator component which animation should be played via Mecanim parameters. If you want to use a custom Animator for your Character, crete a class that implements ICharacterAnimim interface.

Every new cycle tick the Character updates all these systems in a very specific order.

Character Cycle

It starts by calling the Player's system Update() method. This takes the user's input and calls one of the Motion's public movement methods:

  • MoveToDirection()
  • MoveToPosition()

After the Player's system has been processed, the Character calls the Motion system's Update() method. This is where external forces are calculated, such as gravity, sliding through slopes, dashing, jumping, ...

Communication between systems

The Motion system takes into account the Player's system before running the update. A system can access any of the other's systems data before processing its Update() cycle.

After the final Motion movement is calculated, the Character executes the Driver's Update() method. This is where the Transform component is updated based on the movement type provided by the Motion parameter.

After the Driver system is completed, the Facing system starts. Based on the information provided by the Driver and Motion systems it calculates the direction in which the Character should be facing at.

Finally, the Character system calls the Animim's Update() method, which feeds the Animator component with the necessary parameter values based on the information of the rest of the systems.

Modular design

It is important to highlight the fact that each system is independent of the other. You can create a custom animation system by implementing a ICharacterAnimim interface and still use the default Player, Motion and Driver systems.

Player

The Player unit handles how the user interacts with the Player character. If the Character does not have the Is Player field checked, this unit is skipped entirely.

The Player also contains the IsControllable flag that defines whether a character processes the input received or not. This is very useful when a character is in the middle of a cutscene and you don't want the user to have control over the player.

Motion

The Motion unit is the brain of the character. It contains all of its quirks, such as its height, its move speed, terminal velocity and so.

The Motion unit also is in charge of receiving any locomotion commands:

  • MoveToDirection defines a direction towards where the character must go. This method has to be called every frame or the character will stop.
  • StopToDirection stops the character's movement. Useful when the character moves due to its deceleration value.

A character can also be instructed to move to a certain position:

  • MoveToLocation instructs a character to move to a specific location. The Location class accepts a position and/or a rotation.
  • MoveToTransform instructs the character to move to a specific transform's position. If the transform changes its position, the character will follow it until it reaches the target.
  • MoveToMarker is similar to the previous method, but also takes into account the marker's rotation and forces the character to end facing the same direction as the navigation marker.

A character can also follow another target without an end condition:

  • StartFollowingTarget starts following a target and stays within a minRadius and maxRadius distance.
  • StopFollowingTarget instructs a character to stop following a target.

The Motion unit is also responsible for dealing with character's jumps. The Jump() method will instruct a character to perform a jump (or air jump), if it's possible.

Driver

The Driver unit controls how a character moves around the scene: Whether it's using Unity's Character Controller, the Navigation Mesh Agent for obstacle avoidance or a physics-based rigidbody entity.

This unit recieves the locomotion information of Motion and Facing, and transforms it into a physical translation and rotation.

Facing

The Facing unit controls where the body of the character (not the head) points at. By default all characters do not rotate their body unless they are moving; in which case the body rotates towards where the character is moving.

However, there are certain situations where the character might want to temporary face at a certain direction. For example, when the character aims with the gun at a certain object, or when talking to a character. Game Creator comes with a layer system that provides a neat solution for these cases.

Recommendation

If you plan on creating your own facing system, we recommend creating a class that inherits from CharacterFacingBase instead of the interface ICharacterFacing. This base class comes with the layer system built out of the box, so you don't have to recode it.

The Facing system interfaces provides access to 3 methods:

  • int SetLayerDirection(int key, Vector3 direction, bool autoDestroyOnReach)
  • int SetLayerTarget(int key, Transform target)
  • void DeleteLayer(int key)

The first two methods, SetPlayerDirection and SetLayerTarget allow to make the character look at a certain direction or keep track of a particular scene object. Making the character change its default direction is done using a layer system.

When any of these methods is called for the first time, it creates a new entry in the layer system and returns its identifier: an integer known as key. To subsequently update a particular layer, simply pass as the key argument the resulting key from the previous iteration.

For example, if you want to make a character look at a certain character (defined by the variable lookAtTransform), you'll simply need to call:

private int key = -1;
public Character character;
public Transform lookAtTransform;

public void StartFacing()
{
    ICharacterFacing face = this.character.Facing.Current;
    this.key = face.SetLayerTarget(this.key, this.lookAtTransform, false);
}

public void StopFacing()
{
    ICharacterFacing face = this.character.Facing.Current;
    face.DeleteLayer(this.key);
}

No Exceptions

It is important to note that the layer system won't throw any exceptions. If you try to attempt to delete a layer but the key doesn't exist, it will simply do nothing.

When calling the StartFacing() method, the character will smoothly rotate towards the target defined until the StopFacing() method is called.

However, in some cases, you may not want to manually remove the facing layer, but instead stop facing a particular direction when the character reaches its target direction. For these cases, simply set the SetLayerDirection method's last parameter to true. This will tell Game Creator to automatically remove the layer when the character reaches its target direction.

For example:

public Character character;
public Vector3 direction;

public void LookAt()
{
    ICharacterFacing face = this.character.Facing.Current;
    face.SetLayerDirection(-1, this.direction, true);
}

Animim

The Animim unit handles everything related to the visual representation of a character: From its appearance to its animations.

Animator required

This unit requires an Animator component reference in order to deal with animations

The default character system comes with a set of procedural animations played on top that add subtle but consistent movement across different animations, such as breathing and exertion. The breathing rate and exertion amount can be modified using the HeartRate, Exertion and Twitching proprerties.