🏃♂️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.
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.
Methods and properties
Once you've derived your controller class from FPSAnimController, let's see what methods and properties this class brings:
// 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);
}
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;
}
InitWeapon(FPSAnimWeapon weapon)
public void EquipWeapon()
{
//... your EquipWeapon() implementation
InitWeapon(weapon); //weapon is a reference to the active weapon
}
InitAimPoint(FPSAnimWeapon weapon)
public void ChangeScope() // Called when changing scopes
{
InitAimPoint(weapon); //weapon is a reference to the active weapon
}
UpdateAnimController()
private void Update()
{
//... Your Update() implementation
UpdateAnimController();
}
PlayCameraShake(FPSCameraShake shake)
[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
private void UpdateActionInput()
{
//... UpdateActionInput() implementation
if (Input.GetKey(KeyCode.Q))
{
charAnimData.leanDirection = 1;
}
else if (Input.GetKey(KeyCode.E))
{
charAnimData.leanDirection = -1;
}
//... UpdateActionInput() implementation
}
Movement
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