🏃‍♂️Character

In this section you will learn how to implement FPSAnimController

Step 1 - Implement FPSAnimController

Inherit your controller from FPSAnimController

Locate your character controller class and derive it from the FPSAnimController - an abstract MonoBehavior class, which acts as an interface between your controller and the rest of the system.

FPSController.cs
public class FPSController : FPSAnimController // <- 
{
    ...
}

If direct inheritance is not possible (e.g. when your controller is already derived from another class), you can try deriving your parent class or creating a standalone controller for the animation part only.

Example

Let's create a standalone animation controller:

YourAnimController.cs
public class YourAnimController : FPSAnimController // <- 
{
    ...
}

After that, attach YourAnimController component to your character. You will need to update YourAnimController with player actions, such as move or look input, etc.

Methods and properties

Once you've derived your controller class from FPSAnimController, let's see what methods and properties this class brings:

FPSAnimController.cs
// Mostly used internally 
protected void InitAnimController()

// Used to initialize the system and pending components
// @cameraDelegate - your function for the camera update
protected void InitAnimController(CoreToolkitLib.PostUpdateDelegate cameraDelegate)

// Used to initialize weapon-related data, such as sway, viewmodel, etc.
protected void InitWeapon(FPSAnimWeapon weapon)

// Used to initialize active aim transform
// Used by the Ads Layer
protected void InitAimPoint(FPSAnimWeapon weapon)

// Should be called every frame in the end of the player update loop 
protected void UpdateAnimController()

// Used to play a recoil shake when firing
protected void PlayCameraShake(FPSCameraShake shake)

// Used to play a static pose
protected void PlayPose(AnimSequence motion)

// Used to play dynamic animation from code
protected void PlayAnimation(AnimSequence motion, float startTime = 0f)

// Used to stop currently playing animation
protected void StopAnimation(float blendTime = 0f)

Use examples

Let's see how these methods and properties should be implemented and used in your controller class:

InitAnimController(PostUpdateDelegate cameraDelegate)

private void Start()
{
    //... your Start() implementation
    
    InitAnimController(UpdateCameraRotation);
}
FPSController.cs
private void UpdateCameraRotation()
{
    Vector2 finalInput = new Vector2(_playerInput.x, _playerInput.y);
                  
    var inputRot = Quaternion.Euler(finalInput.y, finalInput.x, 0f);
    cameraHolder.rotation = transform.rotation * inputRot;

    var freeLookRot = Quaternion.Euler(_freeLookInput.y, _freeLookInput.x, 0f);
    mainCamera.rotation = cameraHolder.rotation * freeLookRot;
}

Tip: UpdateCameraRotation is used to stabilize the camera, so it's not affected by the animations.

InitWeapon(FPSAnimWeapon weapon)

FPSController.cs
public void EquipWeapon()
{
    //... your EquipWeapon() implementation

    InitWeapon(weapon); //weapon is a reference to the active weapon
}

InitAimPoint(FPSAnimWeapon weapon)

FPSController.cs
public void ChangeScope() // Called when changing scopes
{
    InitAimPoint(weapon); //weapon is a reference to the active weapon
}

UpdateAnimController()

FPSController.cs
private void Update()
{
    //... Your Update() implementation
    UpdateAnimController();
}

PlayCameraShake(FPSCameraShake shake)

FPSController.cs
[SerializeField] private FPSCameraShake shake;

private void Fire() // Called when a shot is fired
{
   //... Your Fire() implementation
   PlayCameraShake(shake);
}

FPSCameraShake is a scriptable object, used to play camera shakes when firing. You can create a new camera shake by right-clicking in any folder Create->FPS Animator->FPSCameraShake

PlayAnimation(AnimSequence motion)

[SerializeField] private AnimSequence reloadClip;

private void Reload()
{
    //... Your Reload() implementation
    PlayAnimation(reloadClip);
}

StopAnimation(float blendTime = 0f)

private void OnSprintPressed()
{
    //... Your OnSprintPressed() implementation

    StopAnimation(0.1f);
}

Step 2 - Refresh input

Once all methods are implemented, it's time to properly update the input in runtime.

charAnimData property is responsible for all player-related input, such as leaning, movement, mouse delta, etc.

It won't be updated automatically, you need to insert the input-related logic into your code when a specific key or event is triggered. Here's the examples from the demo:

Leaning

FPSController.cs
private void UpdateActionInput()
{
    //... UpdateActionInput() implementation
    
    if (Input.GetKey(KeyCode.Q))
    {
        charAnimData.leanDirection = 1;
    }
    else if (Input.GetKey(KeyCode.E))
    {
        charAnimData.leanDirection = -1;
    }
    
    //... UpdateActionInput() implementation
}

Tip: 1 defines right, and -1 defines left leaning direction.

Movement

FPSController.cs
private void UpdateMovement()
{
    float moveX = Input.GetAxisRaw("Horizontal");
    float moveY = Input.GetAxisRaw("Vertical");
    
    charAnimData.moveInput = new Vector2(moveX, moveY);
    
    //... UpdateMovement() implementation
}

Look

private void UpdateLookInput()
{
    float deltaMouseX = Input.GetAxis("Mouse X") * sensitivity;
    float deltaMouseY = -Input.GetAxis("Mouse Y") * sensitivity;
    
    charAnimData.AddDeltaInput(new Vector2(deltaMouseX, deltaMouseY));
    
    //... UpdateLookInput() implementation
}

Step 3 - Refresh RecoilAnimation

The last step of the character integration is RecoilAnimation component. Here's what methods and properties you need to use in your controller class:

Update isAiming

private void EnableAiming()
{
    recoilComponent.isAiming = true;
}

private void DisableAiming()
{
    recoilComponent.isAiming = false;
}

Call Play and Stop

private void Fire() // Called when a shot is fired
{
    recoilComponent.Play();
}

private void FireReleased()
{
    recoilComponent.Stop();
}

At this point character integration is fully complete. In the next section, you will learn how implement animation interface for your weapon class.

Last updated