๐Ÿ“‘Animator Profiles

In this section you will learn about new layer system.

Legacy system

In previous versions of the FPS Animation Framework, we had a fixed amount of animation layers, specified directly in the FPSAnimator component:

Legacy system.

The problem with this design is obvious - scalability. What if we want to add an unarmed state? Or maybe swimming? What if we want a unique animation feature for this specific weapon?

The new Scriptable Animation System eliminates this problem by introducing a dynamic linking system for animation features.

Dynamic Linking

This concept is incredibly simple - animation feature encapsulation. To achieve this, the new system relies on Animator Profiles:

Profiles!

An Animator Profile is a Scriptable Object, that contains procedural animation features (FPSAnimatorLayerSettings). There are no limitations on how to use a profile. Whether it is a weapon, item, or a climbing state - it is possible to add custom features required for a specific gameplay scenario.

Here is how to link a new animator profile:

FPSController.cs
private void EquipWeapon()
{
    ...
    _fpsAnimator.LinkAnimatorProfile(gun.gameObject);
    ...
}

In this example, we dynamically link an Animator Profile from the currently equipped weapon. For items and weapons, there's a special component called FPS Animator Entity:

Entity can be a weapon or an item.

This is just a data component, that contains an Animator Profile and a Default Aim Point transform (the Ads Layer uses it).

Procedural Animation Features

A procedural animation feature consists of 2 entities:

  • Animation Layer Settings: a Scriptable Object that contains feature data.

  • Animation Layer Job: a struct that runs the procedural animation logic.

Animation Layer Settings asset is also responsible for instantiating a new Animation Layer Job when a new Animator Profile is linked. This is how it is handled in code:

FPSBoneController.cs
protected void LinkAnimationLayers()
{
    foreach (var setting in _newProfile.settings)
    {
        var job = setting.CreateAnimationJob();
        if (job == null) continue;
                
        job.Initialize(_layerJobData, setting);
        job.UpdateEntity(_entity);
                
        var playable = job.CreatePlayable(_playablesController.playableGraph);
                
        _animationLayers.Add(new AnimationLayer()
        {
            job = job,
            playable = playable
        });
    }
}

Last updated