I have looping and cyclic animation called ‘run’ on a 3D model. Please take a look and observe that at the end of every cycle there is a tiny pause. This is from JME3 game:
Since it’s a cyclic animation, its first and last frame is the same and that causes the pause:
In Blender, it doesn’t cause an issue because by default the Playback Frame Range is set to 1 to 16, so the 0 frame is skipped and when it reaches the 16 frame it interpolates back to the 1 frame so there is no ‘pause’ at the end of the animation because of duplicate frames.
As far as I know there is no way to restrict animation playback in JME like this so I came up with the solution: I removed the last 16th keyframe (which is a duplicate of the 0th keyframe ) so from the 15th keyframe should interpolate to 0th frame and make the pause disappear:
However my problem is that the pause is still there. I also made a version where I removed the 0th keyframe and the pause is still there in JME but works perfect in Blender. It looks like that JME skips interpolation between the last and first frame. Did I configure something wrong? Am I using animcomposer the right way? I don’t understand what is going on.
Edit: It is also pauses at the end of loops in the JME SDK, when I freshly export to glb from Blender then right click > ‘convert to j3o binary’. Opening the j3o file has the same pauses.
Update: It looks like Blender GLB export does something unwanted. I have a 15 frame version of the run animation called ‘run_edited’ where I removed the 16th frame. So there are total 16 frames from 0 to 15 and it should loop perfectly in JME. However, after I exported the file as GLB, I imported it to a new empty blender project and this 16 frame long animation is exported as 17 frame long, the last two frames as duplicates of each other. I’m playing around with export settings now.
I hope you figure this one out. It has long plagued all of my animations in Mythruna and I’ve just resolved to “deal with it later”.
…but for my run and walk animations, I’ve carefully tuned the animations so that the feed don’t slide on the floor when at the proper speed of motion and it always bugs me to see that one frame slip every time.
So I managed to make things better, but I still have this slight pause but not as severe as before.
In my exported animation there was an extra duplicate frame at the end. The reason for this was that Manual Frame Range was enabled on the ‘run_edited’ Action (also on some other actions) and the End frame was set not to the last 15th frame that contained the last keyframe but to 16. This caused the Blender GLB exporter to sample one more frame and it took the last frame at put it in there a second time.
After turning this off the pause became much less noticeable but it is still there. It is more noticeable in the JMonkeyEngine SDK if I convert to j3o and preview it. It is less noticeable in the game loading up the same j3o file but it is still there and makes me go crazy.
Putting Blender, my previous gif and the game windows side by side it is clearly visible that I made things better but there is still a little tiny bit pause there. I’m on 3.4.0-stable by the way.
You may fine tune it further with ClipAction.setTransitionLength(). It sets the animation transition duration. (e.g. when animation switched or restarted). In another word, if you set it to 0, it will instantly jump back to the beginning, when animation ended. Default value is 0.4 seconds.
I suggest you upgrade JME to the 3.6.1-stable version and retest. Each new version of JME always fixes a lot of bugs, it is not a good choice to stay with an old version.
And then follow @Ali_RS 's advice (I’m glad you’re back, it’s been a while since I’ve seen you)
Sorry, I just got to sit down do my own stuff again.
I’m using Blender 3.3.1.
Go to ‘Dope sheet’, then select ‘Action editor’.
Then either select an existing action or add a new one.
Then while the mouse is over the action editor’s ‘Timeline’, press the N key.
I’m reporting back! Haven’t touched game programming seriously for a while. So here is the thing with animations, loops and pauses for future reference:
I’d like to thank @Ali_RS for his comment about ClipAction.setTransitionLength(). This solved the issue for me.
private static final String ANIM_WALK_LOOP = "walk";
// [...]
ClipAction clipAction = new ClipAction(composer.getAnimClip(ANIM_WALK_LOOP));
clipAction.setTransitionLength(0f); // This is the key
composer.addAction(ANIM_WALK_LOOP, clipAction);
composer.setCurrentAction(ANIM_WALK_LOOP);
So when the animation loops, there is a default 0.4f transitionLength on the ClipAnimation. If I set it to 0f, the loop is perfect.