Animancer Parameters are strongly typed, named values stored in a central dictionary for scripts to get, set, and watch for changes.
- Mixer States and Controller States can link their internal parameters to Animancer Parameters so that:
- Other scripts can control their values without needing direct access to the states.
- Multiple states can be linked to the same parameter.
- The Linear Mixer sample demonstrates this feature in action.
- The dictionary uses String References as its keys.
- A parameter of any type can be created, but it can then only contain values of that type.
Cached Example
The most efficient way to access frequently used parameters is to store them in a Parameter<T>
field, where T
is the Generic Argument specifying the type of value it will contain.
public class CachedParameterExample : MonoBehaviour
{
[SerializeField] private AnimancerComponent _Animancer;
[SerializeField] private StringAsset _ParameterName;
private Parameter<float> _Parameter;
On startup, you access the AnimancerComponent.Parameters
dictionary to GetOrCreate
the parameter you want, meaning that whatever system access a parameter with a particular name first will create it then any other system to use the same name will be given the same parameter.
protected virtual void Awake()
{
_Parameter = _Animancer.Parameters.GetOrCreate<float>(_ParameterName);
Then you can listen for any changes to the parameter using its OnValueChanged
event.
_Parameter.OnValueChanged += OnParameterChanged;
}
private void OnParameterChanged(float value)
{
Debug.Log(value);
}
Or get and set its Value
whenever you want.
protected virtual void Update()
{
_Parameter.Value = Time.timeSinceLevelLoad;
}
}
Lazy Example
You can also interact with parameters in the dictionary instead of caching them in a field. This can simplify the code, but is less efficient if it needs to look up the parameter every time.
If the above example wasn't setting the Value
and only needed to listen for OnValueChanged
, it could use AddOnValueChanged
without losing any efficiency.
public class LazyParameterExample : MonoBehaviour
{
[SerializeField] private AnimancerComponent _Animancer;
[SerializeField] private StringAsset _ParameterName;
protected virtual void Awake()
{
_Animancer.Parameters.AddOnValueChanged<float>(_ParameterName, OnParameterChanged);
}
private void OnParameterChanged(float value)
{
Debug.Log(value);
}
It could also use SetValue
, but doing that every frame in Update
would be inefficient because it needs to internally find the parameter from the name every time. Dictionaries allow for fast lookups, but they're still slower than keeping a direct reference.
protected virtual void Update()
{
_Animancer.Parameters.SetValue(_ParameterName, Time.timeSinceLevelLoad);
}
}
Smoothing
Changing a parameter value takes effect immediately, so if you want it to change gradually over time you can use a SmoothedFloatParameter
or SmoothedVector2Parameter
as demonstrated in the Directional Mixer and Brains samples.
public class ParameterSmoothingExample : MonoBehaviour
{
[SerializeField] private AnimancerComponent _Animancer;
[SerializeField] private StringAsset _Parameter;
[SerializeField] private float _ParameterSmoothTime = 0.15f;
Initializing a SmoothedFloatParameter
takes the AnimancerComponent
containing the parameter, a String Reference or Asset to specify its name, and the approximate amount of time you want it to take to reach the target value using the internan Mathf.SmoothTime
.
private SmoothedFloatParameter _SmoothedParameter;
protected virtual void Awake()
{
_SmoothedParameter = new SmoothedFloatParameter(
_Animancer,
_Parameter,
_ParameterSmoothTime);
}
You can then set the TargetValue
on the smoother or simply set the parameter value normally to have it smoothly move towards that value.
protected virtual void Update()
{
_SmoothedParameter.TargetValue = 0;
_Animancer.Parameters.SetValue(_Parameter, 0);
Or you can set the CurrentValue
to move it immediately and cancel any active smoothing.
_SmoothedParameter.CurrentValue = 0;
}
}
Using SmoothedVector2Parameter
is the same as all that, except it takes two parameter names in the constructor and the value is a Vector2
.