-
-
Notifications
You must be signed in to change notification settings - Fork 21.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Methods at the last frame of an animation does not gets called when executed by AnimationTree #61766
Comments
Maybe we can mark the callback function |
AFAIK, AnimationPlayer, AnimationTree and AnimationStateMachine each have a different playback time. Is the problem only with the AnimationStateMachine? Does the problem occur if I playback it in the AnimationTree without using the AnimationStateMachine? |
@TokageItLab I don't know, I've only tested it with AnimationPlayer and AnimationStateMachine. I'll try to test it with AnimationTree and update the MRP, brb. |
@TokageItLab Just confirmed it happens as well for AnimationTree using AnimtionBlendTree, or using AnimationNodeAnimation as root. Didn't test with BlendSpaces though as the other two were easier, would that be needed? Also updated the issue description and the mrp zip. |
Thanks! I remember there was a code somewhere in the core that added the minimum value of double (=CMP_EPSILON) when it reaches the end of the timeline to get the key for the last frame. Perhaps I think the problem is in that area, but I do not know without looking into it in the depth. |
godot/scene/animation/animation_tree.cpp Lines 1337 to 1348 in 7e0c54e
If the delta is small enough, keyframes may be lost here.
I added some print code around this code. Using Playback mode may be backward, pingpong, so, simply replacing with delta<=0 does not solve the problem very well. |
Repost from #61836: |
Another way of thinking, if Longer is acceptable, shorter may lose keyframes. |
I guess when the delay is near zero, it could snap to the end and play the last frame? |
When the delta is small enough for the first time, it is only marked and not processed. Let it be 0 directly the second time. One more step will be ok. |
I looked into AnimationTree. Originally, #61836 state seems to address the fact that it fires continuously when the TimeScale is 0 (Conversely, AudioTrack and AnimationTrack, where that process does not exist, may have a continuous firing problem..). And I think that we need to think of a special case for the end of animation. |
I think For begin-to-end, and end-to-begin, it's linear, so it's easy to compute. For situations where jitter may occur, like pingpong or bouncy balls (The animation may end in the middle, nor is it an unimaginable situation, time is relative, like a number axis of position). Count the number of times if delta is small enough and continue, when the number is big enough, end it and force the |
It is a rare case, but it cannot deal with the case where delta is 0 instead of a very small value at the end of the animation. Rather than using |
The following is the processing logic for
|
The end of animation should be determined by current_time, loop_mode, backward, and animation->length. So setting delta = 0 in that case is fine, but the end flag should be managed at the same time, and using delta == 0 to determine the end of the animation is a bad implementation. |
Couldn’t agree more. So wherever you can get this information, that's a good place for computation. My idea is just to do further processing on the result after the calculation. According to the 4 parameters you mentioned. In the existing implementations, The essence of this issue is that the value field (the delta as value) and the flag field (the delta as end flag) intersect. |
I found a related bug #61853 during testing this. I feel that we need a special case for the processing of the frames at both start and end of animation by any means. I will try to find a consistent solution. |
Will be fixed by #61885. In the past, |
@TokageItLab Haven't found a predictive way to know when one animation will give me trouble or not (and avoid it), I'm not sure if the actual animation length influences this or not, but just realized now my AnimationTree has some BlendSpace1D nodes which it didn't before, so I have to check if the problem happens on the animations they use or not. but the "workaround" I used before still works, which is to either turn off snap and move the method keyframe a few milliseconds back, or increase the length of the animation to be a few milliseconds longer, so it seems like the same problem to me? Edit: I'm also using the AnimationPlayer in FPS mode rather than seconds (except for when I need to change to seconds to do the workaround), so I don't know if this influences anything |
Yeah, just tested the same animation I'm having trouble with on BlendSpace1D in a simple AnimationNodeAnimation and had the same problem, will see if I can separate only the character skin in a MRP later |
Seems to be related to animation length.
|
Please post a new issue along with the reproduction project. If it is due to the precision of the FPS mode, I have a feeling that using floor instead of round for the internal decimal rounding process may solve the problem. |
Godot version
4.0.alpha9
System information
Manjaro Linux, Nvidia proprietary drivers, Vulkan Clustered
Issue description
When controlling animations through an AnimationTree, and there is a method call track with a keyframe on the last frame of the animation, that method call becomes unreliable, working only rarely, and not being called most of the time. The same animation when called through AnimationPlayer, always calls the method correctly.
On further inspection, the error might be because of floating point imprecision, as when I hover the keyframe it shows it's not exactly at 0.4 even though snap is turned on:
This seems to be happening with other frames except multiples of 5, so 0.0 is fine, 0.5 as well, 1.0 too and so on, but any frame values in between are imprecise.
To solve my issue for now I'm just going into the details and manually puting it at 0.39
Not super ideal, as I was already using this as a fix for AnimationPlayer signals being ignored when using AnimationTree (#28311)
--- EDIT ---
Floating point inaccuracy might not be related to the problem: #61766 (comment)
Steps to reproduce
Create any animation that ends on anything other than a multiple of 5 and add a method call to the last frame
Then call this animation through an AnimationTree StateMachine.
Calling the function directly through Animation Player seems to work fine
Minimal reproduction project
floating_point_last_frame.zip
In this project there is a simple scene with three simple animations and one of them calls a function on the last frame that prints a message and emits a signal.
By executing the project and pressing "ui_up" you can play the animation though the AnimationPlayer, "ui_right" through and AnimationTree using BlendTree as root, and "ui_down" through an AnimationTree using AnimationStateMachine as root. Only when playing through AnimationPlayer the method at the last frame is called consistently.
Changing the method call keyframe position from 0.4 to 0.39 fix it for both AnimationTrees.
The text was updated successfully, but these errors were encountered: