godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine
https://godotengine.org
MIT License
91.03k stars 21.18k forks source link

AnimationPlayer waits for 2 physics frames before starting #29187

Closed securas closed 4 years ago

securas commented 5 years ago

Godot version: 3.1.1 Stable

OS/device including version: Windows 10

Issue description: AnimationPlayer running in physics process takes 2 frames before starting after call to play. So calling play to start an animation implies waiting 2 frames before the animation actually begins. This is a problem for pixel art where every frame counts and a jump animation starts when the character is already mid-air.

The project attached starts counting frames after a timer triggers the start of an animation. The animation only prints a message on the console but the message should show at frame 0, no delay, or at frame 1, assuming a single frame delay as in Godot 3.0.6. But shows only at frame 2.

test_animation_player.zip

ghost commented 5 years ago

I found it to be one frame and not two. It seems like everything at time zero happens on the following frame.

I've modified your test to be more accurate. test_animation_player.zip

securas commented 5 years ago

Thanks for checking it out @avencherus I think that even though it is one frame, it runs after the node2d physics process and perhaps that is why my tick counter says 2 frames. That is actually what counts for me since I will then have to wait 2 frames before starting the (e.g.) actual jump, in order to synchronize it with the animation.

What puzzled me the most is that I did not have this behavior in 3.0.6. I did not test 2.1.x.

ghost commented 5 years ago

No problem. There has been a fair number of changes to the AnimationPlayer in 3.1, and very many new bugs have been lingering about unaddressed.

Yeah, you'd have to track that kind of tick counter very carefully since the code is fragmented and executing at different points. I generally stick to the scene tree's frame counter.

A partial work around here is to use $anim.seek(0.0, true) to get the animation keyframes to happen immediately. I say partial, because it doesn't execute the function call keyframe.

I tested in 3.0.6, and the transformation keyframes do go immediately, however, the call keyframe still lags behind by 1 frame.

securas commented 5 years ago

I'm trying to use animationtree, which adds another layer of complexity to this issue. So I guess for now I'll stick to traditional animationplayer, no critical method calls or loading textures and try to start the animation one frame ahead of the action. Thanks for the 'seek' workaround... that will help!

KoBeWi commented 4 years ago

This is intended, docs mention this behavior in 3.2 (check the play() method description).

lukostello commented 3 years ago

This is intended, docs mention this behavior in 3.2 (check the play() method description).

@KoBeWi Why wouldn't we always want to update immediately? Seems like its only an improvement if the animations happened after the _process(). If the animations are played anywhere except directly before the render then you risk that they won't get applied.

securas commented 3 years ago

This is intended, docs mention this behavior in 3.2 (check the play() method description).

Actually... The docs did not mention this at the time the issue was raised. Calling it as a documentation issue is an unfortunate habit.

KoBeWi commented 3 years ago

Except it was a documentation issue, about a behavior that wasn't documented. Updating the docs resolved the problem.

Since this is an intended behavior, if you think that it should be changed or maybe play() should have "immediate" argument or something, feel free to open a proposal.

securas commented 3 years ago

I may be mistaken but I think that I raised the issue because the behavior was not present in earlier Godot versions (2.x)

On Tue, Oct 19, 2021 at 8:50 AM Tomek @.***> wrote:

Except it was a documentation issue, about a behavior that wasn't documented. Updating the docs resolved the problem.

Since this is an intended behavior, if you think that it should be changed or maybe play() should have "immediate" argument or something, feel free to open a proposal.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/godotengine/godot/issues/29187#issuecomment-946253342, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAV7RWZIDEETJI7FI4U4YKDUHSXEHANCNFSM4HPWJNRQ . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

KoBeWi commented 3 years ago

Well, it was added for a reason. The old behavior was probably causing problems. Maybe we could make it optional, but it depends if it's possible to warn about potential problems of immediate playing (i.e. if something behaves unexpectedly, the user should be informed about it, so that they can use deferred playing. Similarly to various properties of physics objects).

securas commented 3 years ago

As mentioned above, the main issue with the delay for me was calling methods and loading textures onto sprites. But I admit that I have not looked into this for a while. I'm not sure about the consequences for the upcoming "reset" animation. This may be a significant issue with those.

On Tue, Oct 19, 2021 at 9:09 AM Tomek @.***> wrote:

Well, it was added for a reason. The old behavior was probably causing problems. Maybe we could make it optional, but it depends if it's possible to warn about potential problems of immediate playing (i.e. if something behaves unexpectedly, the user should be informed about it, so that they can use deferred playing. Similarly to various properties of physics objects).

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/godotengine/godot/issues/29187#issuecomment-946260729, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAV7RW34VUC4YC2ZFMD5JGTUHSZNLANCNFSM4HPWJNRQ . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

lukostello commented 3 years ago

@KoBeWi I don't think I got an answer for why we don't process the animations just before rendering? How could it possibly result in unexpected behavior? Seems like we get unexpected behavior from the way we do it now.

elvisish commented 2 years ago

I’m having issues with a oneshot node delayed by a frame or two, running inside an animationtree, is there a fix for getting it to start immediately?