# 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.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://kinemation.gitbook.io/scriptable-animation-system/workflow/integration.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
