The Evaluate
function on an animation curve gets a value at a time.
https://docs.unity3d.com/ScriptReference/AnimationCurve.Evaluate.html
But it's not clear (to me) what time base or units are used.
For ParticleSystem.MinMaxCurve
, this is explicitly described as being evaluated as a normalised 0 to 1 range of values of the curve's duration:
https://docs.unity3d.com/ScriptReference/ParticleSystem.MinMaxCurve.Evaluate.html
Normalized time (in the range 0 - 1, where 1 represents 100%) at which to evaluate the curve. This is valid when ParticleSystem.MinMaxCurve.mode is set to ParticleSystemCurveMode.Curve or ParticleSystemCurveMode.TwoCurves.
For those considering performance: AnimationCurve's Evaluate is very fast in the traditional sense of Unity's MonoBehaviour world, having an inbuilt means of caching the lookup for the surrounding keys, and retention of the last position evaluated, too. Especially fast in loops of evaluation, because of this. Highly old school optimised, by Unity.
However, ParticleSystem.MinMaxCurve's evaluate benefits from and is part of the Jobs friendly updates to the UnityEngine.ParticleSystemJobs features.
In small usages (around 1000 evaluation steps or less), they're about the same. But with Jobs and lots of fine grained evaluation (more than 10,000), the MinMaxCurve gets ahead.
It uses 0
to 1
in the most cases but depends completely how you configure and use yours ... you can easily extend an AnimationCurve
with keyframes before 0
and beyond 1
.
You can however get the duration of your AnimationCurve
so basically you can normalize down any animation curve to a "time" value between 0
and 1
using
public static class AniamtionCurveUtils
{
public static float EvaluateNormalizedTime(this AnimationCurve curve, float normalizedTime)
{
if(curve.length <= 0)
{
Debug.LogError("Given curve has 0 keyframes!");
return float.NaN;
}
// get the time of the first keyframe in the curve
var start = curve[0].time;
if(curve.length == 1)
{
Debug.LogWarning("Given curve has only 1 single keyframe!");
return start;
}
// get the time of the last keyframe in the curve
var end = curve[curve.length - 1].time;
// get the duration fo the curve
var duration = end - start;
// get the de-normalized time mapping the input 0 to 1 onto the actual time range
// between start and end
var actualTime = start + Mathf.Clamp(normalizedTime, 0, 1) * duration;
// finally use that calculated time to actually evaluate the curve
return curve.Evaluate(actualTime);
}
}
and then e.g.
var someValue = someCurve.EvaluateNormalizedTime(someNormalizedTime);