• RuntimesUnreal
  • Animation gets stuck between poses after BeginPlay only

Versy Thanks for the additional clarification. It certainly looks like this is not a problem with the animation being applied repeatedly, but rather a problem with poses that should be reset not being reset. Could you please email us a minimal UE project that can reproduce this problem?: contact@esotericsoftware.com
Please include the URL of this forum thread in the email so we know the context. Then we can take a look at what's wrong.

    Related Discussions
    ...

    Misaki Alright, slightly embarrassing, but I've isolated the problem to a modification to SpineSkeletonAnimationComponent.cpp that I had someone do for me in order to get a specific framerate on my animations. I thought to check this before but completely forgot.


    I'm not the coder, but I believe what this is doing is only updating the skeleton on a lower interval instead of deltaTime, to mimic a low framerate. But that is likely causing updates to be "caught" in the middle.

    I know this is probably out of your support range because it's a modified feature, and I assume a faux "framerate" option like this isn't planned to be added to the runtime, so if you have any idea if there's a way to get this to play nice with the skeleton update please let me know! 🙏

      Versy I'm glad you were able to narrow down the problem to some extent! However, the code you showed us does not seem to be wrong, would you still be willing to email us a minimal UE project that can reproduce the problem? Then we can look into it in more detail.

        4 天 后

        Misaki Sure thing I'll do that now! I put the code in your Spine example project file and it produces the same issue. Thank you for looking into it!

          Versy Thanks for providing the UE project files! I wasn't sure at what level you were supposed to check, so I just wanted to make sure I was correct that the behavior you see in the following video is the problem you're encountering?:

          The procedure to reproduce this is to press the H key to make Spineboy walk to the left for a moment, then release the H key.
          Some of Spineboy's poses will then be incorrect, but the idle animation itself seems to be applied, and you can see that some bones are animated correctly.

          As far as I could tell from several attempts, this problem did not seem to occur all the time, just occasionally. It certainly seems to be a problem with the mix, as you mentioned that if you set the mix time to 0, this problem does not occur. Once we can confirm that this is the problem you are experiencing, we will investigate the cause.

            Misaki Yes that's correct! Apologies I meant to mention the level. This is indeed the issue I'm experiencing. Please let me know if you figure out the cause!

              Versy Thank you for your response! Our runtime development team is currently engaged in high-priority tasks, and we anticipate that investigating this issue may take some time. We will provide an update in this thread as soon as we have further information.

                Misaki Thank you, and that's totally fine. I have my strange "workaround" for now, and plenty of other things to work on. Cheers!

                  6 天 后

                  Versy

                  It took long, but we finally should have discovered the issue. There is a fix to port to C/C++ runtimes that we still have in our queue. Here you can find the GitHub issue.
                  You can manually port it, or just wait until tomorrow when I will port it. But you'll need to copy it to your project eventually.

                  There's an additional consideration. Now that you are reducing the framerate, you could consider skipping updates where delta is 0. There are currently consecutive state and skeleton update invocations when Step is 0, leading generally to a waste of resources. If you place:

                  if (Step <= 0.0f) return;

                  in your code, you won't have the issue you reported even if you don't port the fix if you return when Step <= 0.0f.

                  Little update, we've just ported the fix 🙂

                    Davide

                    Thank you so much for the update and the advice!

                    I downloaded the new runtime and copied my code over to SpineSkeletonAnimationComponent.cpp again, but now the animation speed itself slows down, not the "framerate". Even without the if (Step <= 0.0f) return; it's doing this.😟 A bit hard to tell from the GIF but it's just playing all frames in slow-motion now, not skipping frames.

                    Did something change significantly in this update that changes the way the animations play so that the code I have won't work anymore?

                    If it's perhaps an oversight on my end please let me know!

                      Versy

                      Are you sure you didn't make any other modifications to our runtime? The fix we implemented is in the spine-cpp runtime, which is a requirement for spine-ue and should be manually copied as described in step 6 of the Installation paragraph in the spine-ue guide.

                      If you've done all of the above, I need to ask you to again send over a project that reproduces this issue, as I cannot reproduce the slow motion problem you're experiencing on your end.

                      Versy

                      I’ve been thinking more about your code, and I suspect the slow motion you’re experiencing might be caused both by your implementation and potentially by your machine.

                      When you calculate Step like this:

                      Step = Accumulate - FMath::Fmod(Accumulate, ActualFPS);

                      If, for any reason, Accumulate exceeds twice the ActualFPS, you’re only advancing your timeline by one step, when in fact you should be advancing it by two steps.

                      I also remembered we have a Unity example that does something similar here. I adapted the logic to C#:

                      float Step = DeltaTime;
                      if (bDisableInterpolation)
                      {
                      	Accumulate += DeltaTime;
                      
                      	const float FrameDeltaTime = 1.0f / DiscreteFPS;
                      	constexpr int32 MaxFrameSkip = 5;
                      	int32 FramesToSimulate = 0;
                      
                      	while (Accumulate >= FrameDeltaTime)
                      	{
                      		FramesToSimulate++;
                      		if (FramesToSimulate > MaxFrameSkip)
                      			break;
                      
                      		Accumulate -= FrameDeltaTime;
                      	}
                      
                      	if (FramesToSimulate == 0)
                      		return;
                      
                      	Step = FramesToSimulate * FrameDeltaTime;
                      }

                      The MaxFrameSkip should prevent steps from getting too large.

                      Let me know if this version works better.