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

Related Discussions
...

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

  • Misaki님이 이에 답장했습니다.

    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.

    • fengmin님이 이에 답장했습니다.

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

      • Misaki님이 이에 답장했습니다.

        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().

        • fengmin 님이 이 게시물을 좋아합니다..

        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.

        • fengmin님이 이에 답장했습니다.
        • Misakifengmin 님이 이 게시물을 좋아합니다..

          Harald 所以是因为在“attack”动画End或Complete时,SetEmptyAnimation()的这个EmptyAnimation本身也会带有End 和 Complete回调并且被瞬间执行,导致了无限循环,那么同理这里使用AddEmptyAnimation()是否也会无限循环,EmptyAnimation的名称是什么,我可以通过在开头进行非空判断来避免循环吗,例如
          private void AttckAnimalComplete(TrackEntry trackEntry)
          {
          if(trackEntry.Animation.Name.Equals(""))
          return
          isAttk = false;
          SetEmptyAnimation();
          }

          @fengmin You can use trackEntry.IsEmptyAnimation.
          http://esotericsoftware.com/spine-api-reference#TrackEntry-isEmptyAnimation

          In general as Misaki pointed out already, it would be far more recommended to call AddEmptyAnimation() directly after setting e.g. the attack animation.

          Also, it would likely be better to call attackTrackEntry.Complete += AttckAnimalComplete instead of registering it at animationState.Complete += AttckAnimalComplete, as you then receive the callback with every completed animation and not only your attack animation.

          • fengmin 님이 이 게시물을 좋아합니다..

          Misaki 最后我想问一下我该在什么地方注销我的complete事件注册,下面的例子正确吗
          Spine.TrackEntry trackEntry = attackAnimator.SetAnimation(0, "attack", false);
          trackEntry.Complete+= AttckAnimalComplete;
          animationState.AddEmptyAnimation(0, 0, 0);

          void AttckAnimalComplete(TrackEntry trackEntry)
          {
              isAttck = false;
              trackEntry.Complete -= AttckAnimalComplete;
          }
          • Misaki님이 이에 답장했습니다.

            fengmin Unfortunately, I don't really understand what you're trying to do. The TrackEntry object is disposed after the End event and issuing a Dispose event. So in general, there should be no need to deregister.

            • fengmin님이 이에 답장했습니다.

              @fengmin Misaki is correct, you can safely remove the line trackEntry.Complete -= AttckAnimalComplete;, you don't need to unregister manually.

              • fengmin 님이 이 게시물을 좋아합니다..