KybernetikGames / animancer

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

Transitioning from a mixer transition asset to itself using FadeMode.FromStart #299

Closed slowhei closed 1 year ago

slowhei commented 1 year ago

I would like to transition from a LinearMixerTransitionAsset.Unshared to itself using FadeMode.FromStart. To avoid performance issues, I want to somehow clone its AnimancerState beforehand. I plan to have my code alternate between playing the two states.

I haven't been able to figure out how to do this. I've tried making two AnimancerStates with different keys, but StateDictionary does not have a function that lets me create a state for a mixer with a key.

Is there an easy solution to this?

KybernetikGames commented 1 year ago

Transitions have a method to create their state, so something like this:

var state1 = transition.CreateState();
var state2 = transition.CreateState();

state1.Key = transition;
state2.Key = state1;// This is what lets FadeMode.FromStart find the next state in the chain if the first is unavailable.

animancer.Layers[0].AddChild(state1);
animancer.Layers[0].AddChild(state2);
slowhei commented 1 year ago

When you say that state2.Key = state1 will let FadeMode.FromStart find the next state in the chain, do you mean that if I call AnimancerComponent.Play(state1), but Animancer is already playing state1, state2 will be transitioned to instead?

When I tried this, it did not work. I also tried playing state2 when state2 is already playing.

(Creating two states with different keys is working by the way. Thanks!)

KybernetikGames commented 1 year ago

animancer.Play(state1, fadeDuration, FadeMode.FromStart); should let it use state2 if state1.Weight > AnimancerLayer.WeightlessThreshold (default 0.1).

It might be easier to pass the transition into Play instead of the state so you don't need to manually keep track of those states after creating them, it should be able to just use whichever has the lowest weight whenever you tell it to play. Note that it would also create more clones if they're both above the threshold unless you lower the AnimancerLayer.MaxCloneCount.

slowhei commented 1 year ago

Ah, my bad. I forgot to specify FadeMode.FromStart in my call to animancer.Play(). Now the chain is indeed working.

However, passing the transition into Play does not. A new AnimancerState is created, and I think it's because I'm using an unshared transition asset.

KybernetikGames commented 1 year ago

Yeah, the key will be wrong in that case.

state1.Key = transition.Key; should work properly.

slowhei commented 1 year ago

Awesome! That did the trick. It seems like UnShared.State is updating based on which AnimancerState is actually playing, which is really convenient.