KybernetikGames / animancer

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

State event not work as (my?) expected #372

Closed SMxSoMuch closed 1 day ago

SMxSoMuch commented 2 weeks ago

I set up a TransitionAssetevent with StringAsset: image

Then do this:

protected override void OnEnable() {
    base.OnEnable();

    AnimancerState state = Anim.Play(attack);
    AssignExit(state);
    state.Events(this).OnEnd = () => Finish();
}
void AssignExit(AnimancerState state) {
    if(state.Events(this, out AnimancerEvent.Sequence events)) {
        events.SetCallback(CanExit, () => CanExitNow());
    }
}

What i expected is: Play > CanExit event fired > OnEnd fired And it work!

But not with this 2 lines swapped:

    state.Events(this).OnEnd = () => Finish();
    AssignExit(state);

which only do: Play > OnEnd fired

I found out it didn't enter the if in AssignExit() which means it basically didn't register.

I would like to know is that intentional or why it didn't work?

KybernetikGames commented 2 weeks ago

Both state.Events methods ensure that the state creates its own copy of whatever event sequence it has been given so that the callbacks you assign only apply to that state and don't go back into the TransitionAsset where they would affect every character sharing that asset.

The if(state.Events(... method only returns true if the state hasn't already done that so you can initialize the state's events the first time it's played without wasting performance repeating that initialization every time the same animation is played. So doing the other call to state.Events(this) first would prevent that if from ever being true.

I would recommend doing both the events.SetCallback and events.OnEnd = inside that if statement instead of getting the events from the state twice as noted in the tooltip of the state.Events(this) method.

SMxSoMuch commented 2 weeks ago

IC. So the state.Events(this... basically act like a bool Initialized. if i want to assign a different one every time when onenable, i should cache it and just events.SetCallback()

KybernetikGames commented 2 weeks ago

Yeah, it's essentially "if the event sequence isn't initialized yet, give it to me so I can initialize it".

If you want to assign events every time, caching would be fine or you can just use state.Events(this) to get it each time.