KybernetikGames / animancer

Documentation for the Animancer Unity Plugin.
66 stars 8 forks source link

Is it possible to set NormalizedTime but still trigger the events before it? #296

Closed kodra-dev closed 1 year ago

kodra-dev commented 1 year ago

I tried this:

var state = layer.Play(clip);
state.NormalizedTime = 1;

The clip has an event at 0 seconds, and it doesn't get triggered.

I tried this workaround:

var state = layer.Play(clip);
state.speed = 100;

It works, but it feels a bit hacky... and it only works when I want to end the clip immediately. What if I want:

var state = layer.Play(clip);
state.NormalizedTime = 0.5f;

And to still trigger all the events before 0.5?

KybernetikGames commented 1 year ago

state.MoveTime should do what you want.

kodra-dev commented 1 year ago

state.MoveTime should do what you want.

But the document says:

Sets the <see cref="Time"/> or <see cref="NormalizedTime"/>, but unlike those properties this method
applies any Root Motion and Animation Events (**but not Animancer Events**) between the old and new time.

Sorry, I didn't make it clear enough. I mean to trigger Animancer Events too.

KybernetikGames commented 1 year ago

The comment is wrong. I can't remember if it originally worked like that or I just thought it would and forgot to test it, but I just added a unit test to verify that Animancer Events aren't skipped when using MoveTime.

Here's a better comment for that method:

/// <summary>
/// Sets the <see cref="Time"/> or <see cref="NormalizedTime"/>, but unlike those properties this method
/// does not skip Events or Root Motion between the old and new time.
/// </summary>
/// <remarks>
/// The Events and Root Motion will be applied during the next animation update. If you want to apply them
/// immediately you can call <see cref="AnimancerPlayable.Evaluate()"/>.
/// <para></para>
/// Events are triggered where <c>old time &lt;= event time &lt; new time</c>.
/// <para></para>
/// Avoid calling this method more than once per frame because doing so will cause Animation Events and Root
/// Motion to be skipped due to an unfortunate design decision in the Playables API. Animancer Events would
/// still be triggered, but only between the old time and the last new time you set (any other values would be
/// ignored).
/// </remarks>
kodra-dev commented 1 year ago

Ah, I see. I tested on our game and yes it does trigger Animancer event. Thank you very much.

Small suggestion: maybe the comment could clarify what "between old and new time" means. old <= now < new or old <= now <= new or...

KybernetikGames commented 1 year ago

Good idea, I've edited my previous comment. In plain text, that's:

Events are triggered where old time <= event time < new time.