# Integration

**FPS Animation Framework** offers a streamlined integration process. Let's start with the custom controller integration. We will use the FPSController script from the demo project as an example.

## Initialization

First, you need to add references to the framework core components:

```csharp
private FPSAnimator _fpsAnimator; // Central management component.
private UserInputController _userInput; // Dynamic input system.
private FPSCameraController _fpsCamera; // Camera system.
private IPlayablesController _playablesController; // Dynamic animation system.
private RecoilAnimation _recoilAnimation; // Recoil effect component.
```

Then, make sure to initialize all the components:

```csharp
_fpsAnimator = GetComponent<FPSAnimator>();
_fpsAnimator.Initialize();
_userInput = GetComponent<UserInputController>();
_fpsCamera = GetComponentInChildren<FPSCameraController>();
_playablesController = GetComponent<IPlayablesController>();
_recoilAnimation = GetComponent<RecoilAnimation>();
```

{% hint style="danger" %}
**Note**: make sure to initialize the **FPS Animator** component!
{% endhint %}

## Updating Input

When updating user input, we typically need to refresh aiming and movement inputs:

{% code overflow="wrap" %}

```csharp
private void UpdateInput()
{
    ...
    _userInput.SetValue(FPSANames.MouseDeltaInput, new Vector4(deltaMouseX, deltaMouseY));
    _userInput.SetValue(FPSANames.MouseInput, new Vector4(mouseX, mouseY));
    _userInput.SetValue(FPSANames.MoveInput, new Vector4(moveX, moveY));
    ...
}
```

{% endcode %}

## Weapon change

When switching weapons, we need to link a new Animator Profile:

```csharp
private void EquipWeapon()
{     
    ...
    _fpsAnimator.LinkAnimatorProfile(gun.gameObject);     
    ...
}
```

## Aiming

```csharp
private void OnAimPressed()
{
    _userInput.SetValue(FPSANames.IsAiming, true);
    _recoilAnimation.isAiming = true;
    _fpsCamera.UpdateTargetFOV(aimFov);
{

private void OnAimReleased()
{
    _userInput.SetValue(FPSANames.IsAiming, false);
    _recoilAnimation.isAiming = false;
    _fpsCamera.UpdateTargetFOV(defaultFov);
}
```

Additionally, we access the **FPSCameraController**, and adjust the target FOV. We also adjust the recoilAnimation aiming status, which is important as it will adjust the animation accordingly.

## Playing animations

To play an animation from code, you need to call the:

```csharp
// Where yourAnimation is an Animation Asset.
_playablesController.PlayAnimation(yourAnimation, 0f);
```

You can also specify the start time of the animation as a second parameter, which might be useful for mechanics like staged reloads.

## Recoil

The recoil is implemented via **Recoil Animation** component and **Camera Shakes**. First, we need to initialize the Recoil Animation component when a gun is equipped:

{% code overflow="wrap" %}

```csharp
_recoilAnimation.Init(gun.recoilData, gun.fireRate, gun.isAuto ? FireMode.Auto : FireMode.Semi);
```

{% endcode %}

You only need to add the **Recoil Data** to your custom weapon class. The Recoil Data is a Scriptable Object, that contains the information about the procedural recoil animation.

Next, we need to apply the recoil effect in runtime:

```csharp
// Called every shot.
private void Fire()
{
    // Make sure to add an FPSCameraShake public field to your weapon class.
    _fpsCamera.PlayCameraShake(GetGun().cameraShake);
    if (_recoilAnimation != null) _recoilAnimation.Play();
}

// Called when firing key is released.
private void StopFiring()
{
    if (_recoilAnimation != null) _recoilAnimation.Stop();
}
```

## Making adjustments

Sometimes it is necessary to adjust our system's behavior in runtime, depending on gameplay situations.

In the **FPS Animation Framework** it is implemented primarily via the Input System:

```csharp
private void OnSprintStarted()
{
    _userInput.SetValue(FPSANames.StabilizationWeight, 0f);
    _userInput.SetValue(FPSANames.PlayablesWeight, 0f);
}

private void OnSprintEnded()
{
    _userInput.SetValue(FPSANames.StabilizationWeight, 1f);
    _userInput.SetValue(FPSANames.PlayablesWeight, 1f);
}
```

In the example above, we toggle the Playables systems and stabilization based on the sprinting status. You can adjust custom properties in a similar way, depending on the requirements of your project.

***

At this point, the integration is complete. In the next section, we will learn more about dynamic animations.
