SkeletonAnimation attackAnimator;
private void OnEnable()
{
Idleanimator.AnimationState.Event+= AnimationEvent;
}
使用SkeletonAnimation 时,可以像这样轻松使用spine event(当spine定义事件被触发时该事件函数就会被调用)
使用SkeletonMecanim该如何在代码中做到类似的效果(我不想在unity animation中手动设置全部的事件)

    Related Discussions
    ...

    Misaki thanks,then i will use SkeletonAnimation

    顺便我想问一下:同时注册多个事件,注册多次事件会导致unity崩溃吗
    例如:

    private void OnEnable()
        {
            Idleanimator.AnimationState.Start += JumpMethod;
            Idleanimator.AnimationState.Complete += IdleAnimalComplete;
            Idleanimator.AnimationState.End += IdleAnimalEnd;
            Idleanimator.AnimationState.Event += CrouchPause;        
            attackAnimator.AnimationState.Complete += AttckAnimalComplete;
            attackAnimator.AnimationState.End += AttckAnimalComplete;        
            attackAnimator.AnimationState.Complete += ResetEventCount;        
            attackAnimator.AnimationState.Event += HandleAnimationEvent;
            attackAnimator.AnimationState.Start += AttackStart;
            attackAnimator.AnimationState.End += ResetEventCount;
        }
        private void OnDisable()
        {
            Idleanimator.AnimationState.End -= IdleAnimalEnd;
            Idleanimator.AnimationState.Complete -= IdleAnimalComplete;
            attackAnimator.AnimationState.Event -= HandleAnimationEvent;
            attackAnimator.AnimationState.Complete -= AttckAnimalComplete;
            attackAnimator.AnimationState.Complete -= ResetEventCount;
            attackAnimator.AnimationState.End -= ResetEventCount;
            attackAnimator.AnimationState.End -= AttckAnimalComplete;
            Idleanimator.AnimationState.Event -= CrouchPause;
            Idleanimator.AnimationState.Start -= JumpMethod;
            Idleanimator.AnimationState.Start -= CrouchMechod;
        }

    我发现:
    attackAnimator.AnimationState.Complete += AttckAnimalComplete;
    attackAnimator.AnimationState.End += AttckAnimalComplete;
    会导致崩溃,AttckAnimalComplete函数只是负责了动画结束时设置一些状态为false;因此我希望在End和Complete都使用,但是却导致了崩溃

      If you receive crashes, you're doing something wrong.
      If you receive a NullReferenceException, likely in OnEnable() your references like Idleanimator.AnimationState are not set up yet. If you're using recent spine-unity versions, accessing skeletonAnimation.AnimationState will initialize it automatically, while on older versions you will need to call skeletonAnimation.Initialize(false);.

      What does the crash say, or what is the exception message saying?

      Noticing the lines:

      Idleanimator.AnimationState.Start += JumpMethod;
      ..
      attackAnimator.AnimationState.Complete += AttckAnimalComplete;

      What is Idleanimator and what is attackAnimator? Are they separate SkeletonAnimation instances? Are you sure that you want to have multiple SkeletonAnimation objects and not a single one which plays all animations?

      Note that you can also register events to a single TrackEntry after starting or adding an animation

      Spine.TrackEntry trackEntry = animationState.SetAnimation(trackIndex, "attack", true);
      trackEntry.Start += OnSpineAnimationStart;

      (See the documentation here or in English here)

        Harald
        unity editor.exe stopped running as soon as I play the game. I commented the code one by one and found that this line was the problem. Since the contents of my function were correct, I wondered if it was caused by my register event

          fengmin I should have told you this earlier, but there is a translation button on the forum so you can post your reply in your native language.

          It looks like you didn't answer Harald's question. Please tell us what Idleanimator and AttackAnimator do.
          Are you trying to have multiple SkeletonAnimation objects?

          If you want to handle the events of the idle animation and the attack animation separately, as Harald suggested, it would be best to use TrackEntry to register only the events for specific animations. Have you tried the code Harald suggested?

          是的,我用来控制多个不同gameobject下的不同SkeletonAnimation对象

          问题是
          attackAnimator.AnimationState.Complete += AttckAnimalComplete;
          attackAnimator.AnimationState.End += AttckAnimalComplete;
          调用的是同一个函数AttckAnimalComplete,如果单独使用.Complete是可以正常运行的,但是End会导致unity停止响应

            fengmin So, could you show us what the AttckAnimalComplete method does?

              Misaki
              isAttk = false;
              isAttked = true;
              playerState.playerState = CharacterState.Idle;
              attackAnimator.state.SetEmptyAnimation(0, 0);
              attackAnimator.state.ClearTracks();

                fengmin Is there any reason why you are using ClearTracks()? As long as you are using SetEmptyAnimation(), I don't think it's necessary, and I guess it might cause the crash.

                  After trying this, Unity froze even if I just called SetEmptyAnimation() on both the Complete and End events, so it seems that the problem is not ClearTracks(), but that you are trying to do these operations on both Complete and End. In fact, I think there is usually no need to call this on both Complete and End, so why is it necessary on both? If you want to call the method when the loop is complete, register Complete, and if you want to call it when the playing animation switches to another animation or finishes playing, register End should be sufficient.

                    Misaki 是的,就是这,我使用ClearTracks是为了在动画播放结束后回到默认姿态,而不是保留在最后一帧,但是为什么会崩溃?是因为触发了多次吗,End和Complete两个事件应该只会触发该方法一次

                    Misaki 也许是因为SetEmptyAnimation?我将SetEmptyAnimation(0, 0);和ClearTracks()都删掉后就没有崩溃了。
                    至于为什么都调用,因为我的攻击动画可能会被打断,也可能正常播放完成,我希望无论如何都需要在攻击动画没有播放时将isAttk = false;

                      fengmin attackAnimator.AnimationState.Complete += ResetEventCount; attackAnimator.AnimationState.End += ResetEventCount;

                      之前我也这样用过End和Complete,执行的ResetEventCount函数负责把一个计数器清零,内容只有eventCount = 0;用于在我的攻击动画结束和被中断时重置我的事件计数。
                      这种方式是可行的,并没有产生任何问题

                      fengmin Unfortunately, I'm not sure why the crashes occur, but I think Harald will answer that later.

                      Anyway, I think there are some solutions. For example, you can modify the code to register a handler for the End event of the TrackEntry and call AddEmptyAnimation() beforehand so that the animation returns to the setup pose when it is complete.

                              Spine.TrackEntry trackEntry = attackAnimator.SetAnimation(0, "attack", false);
                              trackEntry.End += AttckAnimalComplete;
                              animationState.AddEmptyAnimation(0, 0, 0);

                      This way, the End event is fired when the animation switches to the empty animation, so it is sufficient to simply register a method to the End event. This allows you to cover both the case where the animation is complete, and the case where the animation is switched to another before it is complete.

                        Misaki 谢谢
                        删除attackAnimator.state.SetEmptyAnimation(0, 0);
                        attackAnimator.state.ClearTracks();可以解决崩溃问题,虽然暂时不清楚崩溃原因,但是让我可以继续尝试别的方法了

                          fengmin Oh, sorry, I forgot to add that I assumed that the AttckAnimalComplete() would be like this:

                          void AttckAnimalComplete(Spine.TrackEntry trackEntry) {
                             isAttk = false;
                             isAttked = true;
                             playerState.playerState = CharacterState.Idle;
                             attackAnimator.state.SetEmptyAnimation(0, 0);
                          }

                          Please note that ClearTracks() does not reset the pose of the previous animation. This is explained in the API reference: https://esotericsoftware.com/spine-api-reference#AnimationState-clearTracks
                          So you should use SetEmptyAnimation() instead of ClearTracks().

                          Misaki After trying this, Unity froze even if I just called SetEmptyAnimation() on both the Complete and End events, so it seems that the problem is not ClearTracks(), but that you are trying to do these operations on both Complete and End.

                          @fengmin Note that SetEmptyAnimation() or SetAnimation() in general is also triggering End and Complete callbacks. You're creating an infinite loop if you call SetEmptyAnimation() or SetAnimation() from a callback of AnimationState.End or Complete. You need to either register to callbacks of a single TrackEntry like trackEntry.End += YourCallback or use AddEmptyAnimation() as Misaki mentioned above.