top of page

CharacterController

CharacterController uses CharacterMotor to move properly in function of collisions with scene.

Notice that the character is put in Kinematic motion, so CharacterController is responsible for every displacements done by the character.

This allows us to get full control over character dynamic and behaviors. 

 

Finally script handles complete character dynamic in function of inputs, configuration and context in which player is.

More over this offer many services and API so it can be used by other scripts.

Basics

This concerns settings for standard behaviors (walk, run, jump, in air, crouch...).

 

 

Basics
Edge Slide
  • Always Run : is character always running, i.e always using Run Speed

  • Walk Speed : speed when walking (m/s)

  • Run Speed : speed when running (m/s)

  • Acceleration : max acceleration (m/s²)

  • Deceleration : max deceleration (m/s²)

  • Stop On Rotate : makes player stops immediately when changing walk direction, otherwise progressively decelerate

  • Friction Dynamic : friction when pushing input, must be in [0,1] range

  • Friction Static : friction when releasing input, must be in [0,1] range

  • Auto Rotate : character flips itself when input direction change is detected

  • Gravity : gravity acceleration while in air (m/s²)

  • Air Power : input acceleration while in air (m/s²)

  • Ground Flip Max Speed : maximum speed at which player can rotate while on ground

  • Air Flip Max Speed : maximum speed at which player can rotate while in air

  • Max Air Speed : maximum horizontal speed while in air (m/s)

  • Max Fall Speed : maximum downfall speed (m/s)

  • Crouch Size Percent : size scale when crouched

  • Uncrouch Min Speed : minimum speed applied to character if stuck while trying to uncrouch

  • Enable Crouch Auto Rotate : enable/disable player flipping while crouched

  • Auto Move : force character to move automatically in one direction

  • Halt Auto Move : auto move is paused while this input is pushed

  • Slope Speed Multiplier : curve to scale speed in function of slope angle (in degree)

Edge Slide

This allows us to make the character slide down when located near an edge.

This can be needed sometimes if you want your character to fall down when just a small part of the sprite is lying on the ground but most of it is in the air.

These settings are in the Basic configuration settings of the APCharacterController.

 

Technically, the engine detect if one or more rays from the front of the character are not touching the ground whenever character is on the ground.

If this is the case, an horizontal slide force is applied onto the character until it falls down.

 

Character Controller

 

  • Edge Slide Factor : enable the feature if positive only. Amount of power to make the character slide along the ground in order to fall down

  • Edge Slide Min Ray Out : minimum count of rays to lie in the air for activating the sliding force

     

     

     

     

     

     

     

     

     

Down Slope Sliding

Down Slope Sliding

If enabled, this allows player to slide down along slopes only if in stand position (i.e not moving forward).

Indeed this is enabled only in player is releasing any forward input.

When it is active, this is like character is on a icy surface with some gravity applied to it.

 

  • Enabled : enable or not this behavior

  • Sliding Power : sliding power (acts like gravity)

  • Slope Min Angle : minimum slope angle at which behavior is activated

Ground Align

Ground Align

You can setup some special behavior related to ground alignment.

 

  • Ground Align : align player along ground normal

  • Jump Align : jump in direction of ground normal

  • Align Air Move : move player  while in air along its facing direction if enabled or only horizontally if disabled

  • Force In Air Vertical Align : enforce player to always stay aligned with vertical axis

  • Max Angle : maximum slope angle for which ground aligned is applied (0 = horizontal, 90 = vertical)

  • Rotate Speed : maximum rotation speed (degrees/s) used for aligning player with ground normal

     

     

     

     

     

     

     

     

     

Jump through platform

You can jump through platforms so that collision occurs only when landing on the ground.

This is called OneWayGround and this can be setup in Ground Align settings.

You will find more details on dedicated Youtube tutorial.

 

  • One Way Layer : collision layer used to detect one way grounds (i.e all game objects using this layer will be recognized as "Mario style" one way ground objects)

  • One Way Down Jump : allows you to jump down from a one way ground when jump & down buttons are pressed at the same time

Jump through platform

Animations

List of animations name for most moves.

Animations are using new animation mechanism. You'll have to make sure you are using new Animator component. 

Notice that all animations names corresponds to an AnimationState inside the Animator.

 

Animations
  • Min Air Time : minimum time while in air before launching "In Air" animation

  • Walk Anim From Input : if checked, speed of walk/run animation is computed from filtered input, otherwise from ground speed

  • Anim From Input : animation speed in function of input

  • Anim From Speed : animation speed in function of ground speed

     

     

     

     

     

     

     

     

     

You can completely customize/override default animations behavior.
There are differents ways to achieve this, please check Youtube tutorial for more information.

Just keep in mind that each animation can be overrided easily, 
plus you can add more complex behaviors by using available Animator parameters listed below and cool Unity Animator transition system :

  • VerticalSpeed : the vertical speed of the character in m/s, can be used to switch between inair up and inair down animation for example

  • OnGround : tells if the character is touching a ground with its feet or not

  • GroundSpeed : speed of the character along ground surface (valid only if touching the ground)

  • GroundAngleSigned : angle in degrees of the ground the character is lying on, for exemple:  

    • 0 = horizontal

    • 45 = slope up of 45 degrees

    • -30 = slope down of 30 degrees

  • State : current internal state of the character, list is available in State enum of the APCharacterController script : 

    • Standard = 0

    • Crouch = 1

    • WallJump  = 2

    • WallJumpInAir = 3

    • MeleeAttack = 4

    • RangedAttack = 5

    • Glide = 6

    • WallSlide = 7

    • Shift = 8

       

       

       

Inputs

Each input has a name, this must match input name in project input settings, this is the Unity input.

When axis is used, the raw value (i.e value at which input is physically) is always used instead of the Unity filtered value. 

Indeed, we handle our own input filtering mechanism but we use same principles.

 

When a digital input is used for an axis (e.g keyboard or touchpad), some parameters are nonsense and then they are not used.

But some analogical devices (such as joysticks) can have different analog values and may be filtered if needed (e.g DeadZone).

Default values should fit all needs but you can tweak them if really needed.

 

Inputs
  • Axis X/Y : used for horizontal/vertical moves. Each axis has value in [-1, 1] range.

    • Name : name of Unity axis input to use (check you project input settings for name matching => Input Manager)

    • Acceleration : max speed at which input can accelerate (only used for Anim From Input mode, cf. Anims)

    • Deceleration : max speed at which input can decelerate (only used for Anim From Input mode, cf. Anims)

    • Snap : immediate switch from one sign to the other (i.e does not decelerate if changing axis direction suddenly on device input)

    • Force Digital (analog devices) : force value to be digital (result value will only be -1, 0 or 1)

    • Dead Zone (analog devices) : value is always forced to 0 if input device raw value is inside this threshold (only useful for analog devices)

    • Plugin : allows you to override default Unity input raw value, but use yours instead (for example to handle touch input)

      • this is where you reference an EasyTouch plugin script for example

  • Run Button : button to use if Always Run is disabled

    • Name : name of the button in your project input settings => Input Manager

    • Plugin : allows you to override default Unity input raw value, but use yours instead (for example to handle touch input)

      • this is where you reference an EasyTouch plugin script for example

         

         

         

         

         

         

         

         

         

When a button is used inside a specific action (e.g Jump), you will see this kind of configuration if unfolded :

Buttons

Buttons

Name is always the Button name used in Unity Input Manager.

 

Holders is the list of buttons that must be maintained while pressing the main button ('Jump' button in this example)

This allows you to make combination of buttons for launching a specific action.

 

Releasers is the opposite, this is the list of buttons that must be released while pushing the main button.

 

This is to handle properly different actions with same main button but with differents Holders.

For example, you want to jump with the 'Jump' button and you want to launch an attack with 'Jump' + 'A' buttons.

You must add 'A' as a Holder in your attack action, and add it as a Releaser in your Jump action.

Otherwise, pressing 'Jump' + 'A' will sometimes launch the classic Jump action instead of the attack.

Jump

Character can do wall jump. Wall jumping is possible if facing a wall close enough (used by Front/Back ray extra distance) and if jumping at this time.

Player must not touch the ground at this time.

You can activate/deactivate this feature for all objects in the scene.

More over you can override this per game object by using material.

 

Jump
  • Enabled : enabled status (can be updated in script)

  • Button : Unity input button name to use

  • Jump With Vertical Axis : allows to use Y axis defined in Inputs settings to jump

  • Min Height : minimum height when jumping (in meters)

  • Max Height : maximum height if player continues pushing jump button

  • Air Jump Count : number of additional jumps you can make while in air (put 1 for double jump)

  • Air Jump Horizontal Power : defines the horizontal power when doing additional jumps

Wall Jump

Character can do wall jump. Wall jumping is possible if facing a wall close enough (used by Front/Back ray extra distance) and if jumping at this time.

Player must not touch the ground at this time.

You can activate/deactivate this feature for all objects in the scene.

More over you can override this per game object by using material.

Wall Jump
  • Enabled : if true, enabled for all walls in the scene. Otherwise use an APMaterial to allows WallJump on specific wall only

  • Button : Unity input button name to use

  • Jump Power : power to use when jump against wall

  • Horizontal Booster : adds extra power in horizontal axis when jumping

  • Time Before Jump : time to snap player on wall before jumping

  • Time Before Flip : time to flip player after jumping on wall

  • Disable Auto Rotate Time : time to deactivate auto rotate after jumping on wall

  • Ray Indexes : list of rays index to use for detecting front wall, 0 ray means all rays

Wall Slide

When player is moving down while facing a wall and pushing input against this wall then it is going into wall slide.

Wall sliding will switch player animation and change dynamic to simulate wall friction.

Wall Slide
  • Enabled : if true, enabled for all walls in the scene. Otherwise use an APMaterial to allows WallSlide on specific wall only

  • Friction: wall friction during sliding

  • Min Time : minimum time player is sliding before switching animation and changing friction

  • Min Speed : minimum vertical down speed to switch into wall sliding state

  • Ray Indexes : list of rays index to use for detecting front wall, 0 ray means all rays

     

     

     

     

Glide

Glide

You can add special glide ability to your player easily.

  • Enabled : enabled status (can be updated in script or per game object)

  • Button : glide button in Unity inputs

  • Gravity Factor : modify gravity by this factor when glide is active

  • Lateral Move Factor : you can add some lateral air friction

  • Max Duration : maximum time a glide can occur

  • Max Count : maximum glide player can make before touching ground/wall jumping

  • Min Air Time Before Glide : minimum time player is in air before glide is allowed

     

Attacks

You character can launch attacks. 

Mechanism is relatively simple and generic. 

You can add as attack as needed.

 

An attack is defined by an input key, a list of animations (one per context : stand, inair, crouch...) and some settings.

During an attack, you can handle a Melee Attack (hit something with your character body) as well as a Ranged Attack (launch a bullet that will hit something).

Please notice that an attack can be only a Melee Attack, a Ranged Attack or both at the same time!

Attacks
Common Settings
 
  • Enabled : enabled status (can be updated in script or per game object)

  • Size: number of attacks

  • Button: name of input for launching this attack

  • Auto Fire: relaunch attack indefinitely as long as input is hold

  • Context XXX: list of settings used when attack is launched in different context

    • List of contexts

      • Stand : when player does not move and is playing its standing animation

      • Run : when player is running

      • Crouched : when player is crouched

      • In Air : when player is in air

      • Other contexts are not supported for now, but more may come later

    • Enabled : enable to launch an attack while player is into this context

    • Anim : animation to launch for this specific context

    • Stop On Ground : force player to stop move if launching attack while touching ground

       

       

Melee Attacks
Melee Attacks

A Melee Attack needs some HitZone to be defined.

 

HitZone is simply a small sphere used for hit detection with other game objects. You can add as many hit zone as desired to your game object.

To achieve this, you have to create an empty game object under your player game object and add a HitZone script to it.

 

Then under your melee attack configuration, add an element to the array of Hit Zones and point your newly created HitZone game object.

Notice that any hit zone not listed in this array will be ignored.

You can animate your hit zone as you wish in your melee attack animation (local position, radius, active status).

 

By default an HitZone is not active at init. You must change active status inside animation.

Notice that same HitZone can be shared between different melee attacks.

Please check MeleeAttack demo level for easy to learn sample.

Ranged Attacks

During an attack, you can decide to launch a bullet.

Each bullet is launched at desired starting position and into a given direction, these settings are also available for each context.

Your animation must tell when to launch a bullet. To do this, simply add a call to this events into your animation : FireRangedAttack

You can launch many bullets into the same animation.

 

Plus you have some additional settings:

 

  • Ammo: number of remaining ammo

  • Infinite Ammo: allows to have infinite ammo for this attack

  • Bullet: bullet game object to instantiate when spawning a new bullet (see below)

  • For each context :

    • Bullet Start position: start position of the bullet (in local character space), you can use game scene to move it instead of setting directly its value

    • Bullet Direction : launch direction of the bullet

 

Notice that bullet start position is shown as a green sphere when a context is unfolded. 

You can grab the sphere to move it freely in the game scene and position it correctly according to your animation.

Ranged Attacks

A bullet is a simple game object owning the APBullet script.

This script is used to control the dynamic of the bullet and its behavior when touching an element of the game.

The package is provided with a simple bullet script that moves straight forward and explode as soon as it touch something.

 

If the touched object has an APHitable script, it will be warned that a bullet has touched him.

You can override this behavior to implement your own : simply create a new script that inherits APBullet class.

 

Asset may provide more complex bullet dynamics later.

  • Hit Damage: number of hit damage done (used for custom scripting)

  • Velocity: move velocity (m/s) 

  • Acceleration : acceleration (m/s²), can be negative to slow down 

  • Life Time : bullet is destroyed from scene after this time (in seconds) 

  • Stop On Explode : immediate stop bullet when touching something 

  • Destroy Timer : time after exploding before destroying bullet, for example to allow an explosion animation to play entirely 

  • Ignore Trigger : ignore trigger colliders for collision detection 

  • Anim State Explode : animation to play when exploding 

  • Face Right : is bullet facing right in Editor (needed to know if we must reverse bullet at spawn) 

Attack Switcher
Attack Switcher

You can add an Attack Switcher mechanism to you character in order to add a weapon selection system to your GUI.

Please have a look to Ranged Attack scene & AP Sample GUI game object that is instantiated in there for an example of how to implement your own GUI.

​

  • Launch Attack: input used to fire current selected attack

  • Set Previous/Next Attack: input used to select next/previous attack in list

  • Attack : list of attacks (by name) to use for this switcher

  • Current Attack Index : initial & current selected attack index

  • Loop : loop selection

Shift

Shifting is the ability to make the character move along a straight line.

Once a shift key is pressed, the player starts to move from its current position, along a predefined direction, during an amount of time and at a desired speed.

You can add as many as shifting configuration as needed, one for each button.

With this generic approach, you can make an horizontal slide move and also a vertical down jump (check samples scripts for cool vertical down jump crate breakage feature!).

Shift
  • Enabled : activation status of shifting ability

  • Max Count In Air: maximum consecutive shift in air

  • For each shift configuration

    • Button : button used to launch this shift configuration

    • Move Angle: direction move angle (0 = horizontal, 90 = vertical up, -90 = vertical down)

    • Pause Time : pause character for this amount of time before shifting (allows you to play your animation)

    • Move Length : length of path to move along (in meters)

    • Move Speed : move speed (in meters/seconds)

    • Exit Speed : speed at which player should move (in current moving direction) when shifting is ended

    • In Air Only : allow this shift ability only while in air

    • Stop On Hit : stop trying to move if a wall along the path is reached

    • Anim : animation state to launch

       

       

       

       

       

       

       

       

       

Edge Grab

Character is able to grab an edge.

An edge can be grabbed while in the air or while the character is lying on the ground upon the edge.

Depending on the initial grab state, appropriate animation is played.

When the character is grabbing the edge, he is allowed to :

  • release the grab by pushing a move key (according to settings)

  • jump

  • climb up the edge with a special climb animation

 

So you must add 3 animations for your character if you want the 3 features activated, but you can just to enable one if needed.

In order to make an edge grabbing in your scene, you have to add a EdgeGrab game object.

Please use the provided prefab for easier implementation.

 

Technical details : 

 

Settings for the character : 

Edge Grab

Internally, a sphere to detect edge grabs game objects is created at start of the game.

This sphere follows the center of the characters, its radius can be tuned but default provided value should be fine.

It acts like a trigger, thus it is assigned to a specific Layer in your character settings (here called EdgeGrab layer).

Whenever this trigger detects a collisions with an edge grab game object, appropriate animation is launched.

 

Important notice : same collision layer than the one specified in your character must be put on your EdgeGrab game objects. 

This layer should collide only with itself for maximum performance. Your Physic2D layer collision matrix should be as this : 

To make an edge "grabbable", you must put a specific game object on it.

Please use position of the game object as the reference point for your edge corner (as shown below).

This game object's Layer must be assigned to the previously defined Layer in your character settings.

First, an edge grab object is defined by a grab direction so that we know in which direction it is allowed to grab this edge : left or right.

 

Then you can setup your different grabbing enter context, each one having a detection sphere called Handle :

  • Grab in the air (magenta sphere)

  • Grab from the top of the edge (cyan sphere)

 

You can change each sphere position and radius.

Anim slot is used to launch character animation when grab is detected for each entering context.

Please notice that when character enter of the detection sphere, it is first snapped onto this sphere's center, then animation is played.

 

You can setup Input Exit values, theses are the minimum value (between 0 and 1) at which the player must press the corresponding input in order to directly ungrab the edge.

Special value 1 is used to disabled this.

 

You can also allow the player to jump with the Jump Exit setting. A specific exit jump impulse is defined too.

Min Grab Time is used to force the player to grab at least this amount of time in seconds before allowing him to exit.

 

When the edge is grabbed, you can also launch a Climb Up animation with any input key so the player climbs up the edge and leave.

Max Exit Input  is used to clamp the input value when animation ends, indeed if you want to stop your character even if player is pushing forward just put 0 here.

Max Exit Power is used to add additional moving force to your animation if player is pressing move forward key. This force starts to apply at specified Max Exit Power Anim Time, which is an animation ratio between 0 and 1. 

 

Animation is quite handy here, indeed moving a physic object into an animation must be done by moving character root node directly, but this is not possible in Unity to make an animation that move your character in world space. That's why a special node has been added under character game object, this is called the "PhysicAnim" node.

When creating your animations, you can animate this node locally, and the engine will use this in order to move properly the character in world space.

This allows you to move the character locally to the Edge Grab game object within an animation so that it's world space position is updated (and not only the sprite).

 

This part is the most complicated part here, and I recommend you to make your hands with provided prefabs before making your own settings and animations.

Finally, please have a look at my Youtube tutorial in which things should be much clearer.

Events

If you want to do some specific scripting, you can listen to any event launched by the character.

To achieve this, simply create a new class object that inherits the APCharacterEventListener class.

Then override any appropriate method, each method is called when corresponding event occur.

 

You can implement any of desired effect inside each method, this can be used for example to play an audio/fx event whenever the characters jumps, touch the ground, attacks....

Finally make sure to attach your listener properly to the listened character into your Awake method.

Please check the Audio samples to see how it is done!

 


public class APCharacterEventListener : MonoBehaviour
{
    public virtual void OnTouchGround() {}
    public virtual void OnLeaveGround() {}
    public virtual void OnJump() {}

    public virtual void OnGlideStart() {}
    public virtual void OnGlideEnd() {}

    public virtual void OnWallSlideStart() {}
    public virtual void OnWallSlideEnd() {}

    public virtual void OnCrouchStart() {}
    public virtual void OnCrouchEnd() {}

    public virtual void OnWallJumpStart() {}
    public virtual void OnWallJumpEnd() {}

    public virtual void OnAttackStart(APAttack attack) {}
    public virtual void OnAttackBulletFired(APAttack attack, APBullet bullet) {}
    public virtual void OnAttackMeleeHit(APAttack attack, APHitable hitObject) { }
    public virtual void OnAttackEnd(APAttack attack) {}

    public virtual void OnShiftStart() {}
    public virtual void OnShiftEnd() {}

    public virtual void OnEdgeGrabStart(APEdgeGrab grabObject) {}
    public virtual void OnEdgeGrabEnd(APEdgeGrab grabObject) {}

    public virtual void OnLadderCatch(APLadder ladder) {}
    public virtual void OnLadderRelease(APLadder ladder) {}

    public virtual void OnRailingsCatch(APRailings railings) {}
    public virtual void OnRailingsRelease(APRailings railings) {}

}

 

 

Events

Advanced Settings

Controller has some more advanced settings that are contained here. 

Normally default settings should fit all needs, and you should never change these values.

In some really rare cases this may be tuned if you got some specific issues.

Please check comments for more information in APCharacterController.Settings.cs file.

 

bottom of page