-
-
Notifications
You must be signed in to change notification settings - Fork 21.4k
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
Animation travel not working when an animation is looped #79208
Comments
Please make a Minimal Reproduction Project so someone can test this. :) |
Agreed, please add a minimal reproduction project, as these steps are not trivial to follow, otherwise this can't be investigated and will likely be closed:
|
Sorry, I did et have time to make a project. If I make a project, and that we test it inside the animation tree by clicking the button, is that okay. It doesn't work with the travel function in code but I think that's the same with the play button in the animation tree. |
I have a similar problem with transitions in
godot_4_0_3.mp4
godot_4_1.mp4Note that even in Godot 4.0.3, we will get stuck if Xfade Time is set to zero. It's possible to workaround this by disabling loop bit for the ones where we want the animation state to travel, but then those animations won't loop outside of AnimationTree. |
It seems to be the same issue, but I don't understand what's the transition view that you have. On my side, it can be seen in the animation tree : you click on play and the transition / travel doesn't happen |
@jordanlis preferably prepare a simple test project stripped of everything but bare minimum. These can be same issues or different. Test projects are needed to test these cases. Check what @AThousandShips asked of you above for instructions. |
OK I'll spend some time preparing a demo it need to be fixed. |
@jordanlis that's the "auto advance" bit. But I could also do it with a state machine, attached: godot_4_0_3.mp4godot_4_1.mp4 |
I remember this is an intended change by #75759. The length of the looped animation is infinite in order to accurately calculate the length of the nested StateMachine. You can use |
@TokageItLab How do you break out of a looped animation at the end of that animation, next breaks immediately and looped animaitons don't trigger signals? That sounds like what they want to do. |
There are several ways to break out of the loop:
func loop_ended():
if (character.can_transition):
statemachine_playback.next() |
@TokageItLab I hope I'm not misunderstanding. I gave it a try and the 1/ did not wait until the end of the transition be it with or without AtEnd. Am I missing something, please? |
I can't see what you are trying. Even if it is 1 and 2, the xfade time of the transition should be respected. Although, there is no wait for the animation to end, so the user must determine if the animation has looped one loop or not. If you are doing next() during a transition, that would be the intended behavior. It aborts the current transition and start the next transition. |
I was a bit wrong about this. Actually they are not equivalent. next() does not go to the next state unless there is an explicit path there. So if you want to use next(), you need to create a path to the next state with travel() or have a path to the next state with AutoAdvance before you use next(). |
I don't understand where there was any need to prevent the system to allow a transition in the state machine. For me it's a bug --> In the interface, the transition are not happening, what's the need behind the change ? Now, it's not possible to transition from one state to another when an animation is looped ? In code, we need to do that with "next" which is not even waiting for the end frame to happen ? It feels like a gaz factory for nothing... Why did you even do that ? I checked in the mentioned issue and nowhere it is said that the travel function must not work when the animation is looped... Don't want to be rude or anythting, I'm just expressing something here that doesn't feel good for me. |
This was a necessary change for nested StateMachine to xfade correctly. In order to determine the end time of a StateMachine from outside the StateMachine, the StateMachine must have an infinite time length while it is looping. The looping animation should also have an infinite time length to be consistent with it. Before the AnimationStateMachine rework, the loop was broken by AtEnd even though it was looping, but the looping process is redundantly implemented in the AnimationNodeStateMachine, which is separate from the AnimationNodeAnimation. In addition, it did not correctly handle backward loops and pingpong loops, so it was just breaking down.
The implementation of 3 I have described above should work most closely with what you are intending to do. However, it is a bit tedious, and I have heard that @SaracenOne is currently working on a new SwitchMode implementation that will perform transitions when a specified time has elapsed, so it may be better to use that in the future. However, while they may solve the problem for AnimationNodeStateMachine, they may not solve the problem for AnimationNodeTransition.
To be honest, this is the cleanest way to go. However, it is not good way because Animation or AnimationTree as a Resource may be referenced by multiple Nodes. So, in my opinion, it would make sense to implement LoopModeOverride as a parameter of AnimationNodeAnimation, since the AnimationNode parameter is stored in each AnimationTree as a node. This allows us to manage the loop state for each character, even if the same Animation or AnimationTree resource is used repeatedly. Also, this is also beneficial in AnimationNodeTransition. I will send a PR for this later. |
Okay, not really sure to understand your first sentence. Just to make sure that I understand : does your pr will allow looped animation + at end transition to travel to the next animation with
Sorry, I feel that I don't understand everything so it's important for me that you clarify if you don't mind from what I understand about the current solution I need to use next instead of travel and test if the animation has ended. I'll try to make something like that... |
No, looping animation is never AutoAdvanced by AtEnd, nor should it be. This problem is not something that should be solved by the StateMachine, but is fundamentally caused by the fact that AnimationTree lacks an API to manage the looping state of the Animation, so I will add a parameter to manage the looping state in #79400. If you want to break the loop, simply override the loop setting from the inspector of the AnimationTree and disable the loop by the functionality added by that PR. And for example to do it in the script: animation_tree["parameters/Animation/loop_mode_override"] = AnimationNodeAnimation.LOOP_NONE |
No, not autoadvance. Just manually in script or in the animationtree.you see what I mean? |
I still don't get your solution. Your pr will allow to disable the looped animation, so if I Want to go from the looped animation to another, I won't be able to do it until I disable it? And then I have to reactivate it if I need to play it again... And I will be able to wait the end of the animation thanks to the script you put in 3 apparently. I really think that all of this should really stay simple. Like for example a parameter of the next() function that allows to force the transition. What do you think? |
It is not possible. Since the looping animation now has infinite length, it is no longer possible to detect the end of that animation on the StateMachine side. Nor does it solve anything in NodeTransition. The NodeAnimation returns the remaining time when iterating. AtEnd fires a transition when the remaining time falls below a certain value while taking xfade into account, but NodeAnimation now always returns a large constant This change was necessary mostly to fix the following problems:
Also, keep in mind that AnimationBlendTree and AnimationStateMachine are nestable. This means that looping and non-looping animations can blend together. Therefore, the loop must always be detected so that all animations are not interrupted unnaturally. For this reason, looping animations should return a As I have explained many times, you can break out of the loop in several ways:
Footnotes
|
I had the same problem, what I did to solve it in one line of code : Make sure to add state_machine.next() to activate the travelling. |
Godot version
4.1
System information
Windows 10
Issue description
Hi,
I think there's an issue with looping animation and traveling in the animationtree. I think there weren't any issue in the 4.1 RC 2, or previous builds.
I tested it and it was working perfectly fine in the previous build 4.0.3, but not in the 4.1 RC2
There's somewhere an issue with loop animation and travel in animationTree which is incompatible now...
Steps to reproduce
you set up an animation an select the "loop" option
you make a traveling state machine with an animationtree and activate transitions
Make the travel transition to "At end"
you launch the animation with the tree, then try in code with the state machine to travel to the next animation
Expected : the travel is done and the loop is over
Current : not working, the travel doesn't work
Again, was working perfectly fine with 4.0.3. Currently on 4.1 : seems to work with transition "Immediate". The bug is only for "at end" transitions.
Minimal reproduction project
don't have one at the moment, too complicated to create (because I need to make the code and so on)
The text was updated successfully, but these errors were encountered: