You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Godot v4.3.dev3 - Windows 10.0.22621 - Vulkan (Mobile) - dedicated NVIDIA GeForce RTX 3060 Ti (NVIDIA; 31.0.15.4601) - AMD Ryzen 7 5700G with Radeon Graphics (16 Threads)
Issue description
In my project, I'm using a "combined" AnimationPlayer to handle and playback several other animations simultaneously that come from other different AnimationPlayers that were imported with 3D models. I add animation playback tracks from these other players and all works as expected so far.
My issue is that setting a custom speed on this "combined" AnimationPlayer does not transfer to the animation playback tracks -- they all move at 1.0x speed (or the current speed scale of the AnimationPlayer they originate from) regardless. I understand this behavior for things like method calls, where speed scales mean nothing. But I'd expect, since speed has meaning to an animation the way it does for a lerp, that the animation playback tracks would be able to be played backwards / at a custom speed and that an AnimationPlayer that contains an animation playback track could and should set that animation's speed scale to match its own.
Related: It looks like calling seek() on animations that include animation playback tracks does also apply a seek within those animation playback tracks, which makes it odder to me that speed scales aren't inherited/transferred, as this might also lead to unexpected playback behavior at speed scales other than 1.0x.
There is a workaround for this: I can manually set each individual imported AnimationPlayer's speed_scale value at the same time I set the "combined" AnimationPlayer's speed_scale value (or at the time I call play() with a custom_speed). While it does make a little sense that you have to do this once you realize what's happening, I do think that it's far more intuitive and would be expected that the animation playback tracks respect / inherit the speed scale of the AnimationPlayer that's using them.
Steps to reproduce
You can use the minimal reproduction project or recreate the issue from scratch. The use of the term "combined" here is for illustrative purposes as to what the use-case for this is, and to differentiate the node that's being problematic.
If re-creating the issue from scratch:
Add an AnimationPlayer under a parent node (like a Sprite2D), and create a small animation that can be played at any speed scale (a property / position lerp track for example). Making the animation a few seconds long and loopable helps highlight the issue better.
Create another AnimationPlayer under the parent node to serve as a "combined" player, with an animation that simply has an animation playback track pointing to the first AnimationPlayer. Make sure this "combined" animation has the same duration as the other animation you're playing back, and that it is also loopable if the other is.
Create a small script to play the original AnimationPlayer from step 1 at different speed scales, and then do the same for the "combined" AnimationPlayer. You should observe the speed of the animation not changing when using the "combined" player.
If using the minimum reproduction project:
Open the script under the Icon Sprite2D node. play_animated_part() should already be uncommented under _ready() and plays an AnimationPlayer that has a position lerp track for the icon at 1.5x custom speed, and then changes the speed scale to -0.5x speed after 2 seconds.
Comment that function out and uncomment play_combined(), which plays a "combined" AnimationPlayer that has an animation playback track pointing at the AnimationPlayer from step 1. You should observe the speed of the animation remain at 1.0x speed and not change despite the custom_speed argument being set and set_speed_scale() being called after 2 seconds.
You can uncomment the workaround functions if you wish.
The same could be said for AudioTrack, but currently we can only say that this is a specification. I know what is needed, but it will take a major refactoring for keys which have a length to accomplish it.
@TokageItLab It looks like #61897 has this related PR #62498. Is there any chance of this work getting merged in? The inability to play sub-animation tracks backwards is a problem I've just run into. I've tried the workaround @TheRandomDog mentioned, setting imported AnimationPlayerspeed_scale to -1, but that doesn't work to play the sub-tracks backwards. There are some workarounds potentially where I programmatically reverse track keys or something, but that seems like a bad solution.
Old PRs cannot be merged as is, even if they resolve conflicts.
Current Animation lacks a fundamental implementation for length keys in the first place.
Both AnimationPlayback and AudioPlayback only have triggers at the beginning of their keys, and the length only indicates how much processing may or may not continue after the trigger. Also, the playback from their middle is hard-coded and does not support reverse playback.
The problem with #61897 is that it supports reverse playback, but does not care about playback from the middle.
The commonization of playback from the middle and support for reverse playback should be done at the same time, and should be implemented as a separated API from the keys which don't have length, like track_get_segmential_key_by_time().
Tested versions
System information
Godot v4.3.dev3 - Windows 10.0.22621 - Vulkan (Mobile) - dedicated NVIDIA GeForce RTX 3060 Ti (NVIDIA; 31.0.15.4601) - AMD Ryzen 7 5700G with Radeon Graphics (16 Threads)
Issue description
In my project, I'm using a "combined" AnimationPlayer to handle and playback several other animations simultaneously that come from other different AnimationPlayers that were imported with 3D models. I add animation playback tracks from these other players and all works as expected so far.
My issue is that setting a custom speed on this "combined" AnimationPlayer does not transfer to the animation playback tracks -- they all move at 1.0x speed (or the current speed scale of the AnimationPlayer they originate from) regardless. I understand this behavior for things like method calls, where speed scales mean nothing. But I'd expect, since speed has meaning to an animation the way it does for a lerp, that the animation playback tracks would be able to be played backwards / at a custom speed and that an AnimationPlayer that contains an animation playback track could and should set that animation's speed scale to match its own.
There is a workaround for this: I can manually set each individual imported AnimationPlayer's
speed_scale
value at the same time I set the "combined" AnimationPlayer'sspeed_scale
value (or at the time I callplay()
with a custom_speed). While it does make a little sense that you have to do this once you realize what's happening, I do think that it's far more intuitive and would be expected that the animation playback tracks respect / inherit the speed scale of the AnimationPlayer that's using them.Steps to reproduce
You can use the minimal reproduction project or recreate the issue from scratch. The use of the term "combined" here is for illustrative purposes as to what the use-case for this is, and to differentiate the node that's being problematic.
If re-creating the issue from scratch:
If using the minimum reproduction project:
play_animated_part()
should already be uncommented under_ready()
and plays an AnimationPlayer that has a position lerp track for the icon at 1.5x custom speed, and then changes the speed scale to -0.5x speed after 2 seconds.play_combined()
, which plays a "combined" AnimationPlayer that has an animation playback track pointing at the AnimationPlayer from step 1. You should observe the speed of the animation remain at 1.0x speed and not change despite thecustom_speed
argument being set andset_speed_scale()
being called after 2 seconds.Minimal reproduction project (MRP)
MRP-animtracks.zip
The text was updated successfully, but these errors were encountered: