Skip to content
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

AnimationPlayer adds unexpected frame every loop #79244

Closed
JonnyJive5 opened this issue Jul 9, 2023 · 10 comments
Closed

AnimationPlayer adds unexpected frame every loop #79244

JonnyJive5 opened this issue Jul 9, 2023 · 10 comments

Comments

@JonnyJive5
Copy link

Godot version

4.1

System information

Mac OS Ventura AMD Radeon Pro 5500M 8 GB Intel UHD Graphics 630 1536 MB

Issue description

I've been using an 8 directional billboard sprite without issue before. Since moving to 4.1 the sprite seems to hit the first frame on the sprite sheet every cycle of my animation loop. Some of my loops are 2 seconds, some are 4, and it happens in those cycles depending on the state of my agent. I deleted the animation player and when walking around my sprite, the frame rows change correctly without issue leading me to believe the animation player is doing something funky now. Below is a video of my character before the update, then after, where you can see frame 0 (facing the camera) pop up every 2 second animation cycle.

2023.07.06.Godot.4.1.8D.Billboard.Error.mp4

Steps to reproduce

Create sprite 3d (y billboard) with sprite sheet with columns for each animation, and rows for each angle of view. Set frames for the animation player to loop through. For my method, the sprite3d will be a child of a node3d. Make another node3d (named direction_node) as a child of the parent node3d to be used to determine the angle to the player camera.

Use the following code to change columns based on angle of view:

func eight_directional_sprite():
player_position = player.global_transform.origin
# Get the angle to the player
direction_node.look_at(Vector3(player_position.x, direction_node.global_transform.origin.y, player_position.z), Vector3.UP)
direction_node.rotation_degrees.y += 180
var forward_direction = int(direction_node.rotation_degrees.y)
direction_node.rotation.y = rotation.y

# Determine the direction relative to the player's angle out of 8 directions
var sprite_frame_row = forward_direction / 45

# Choose the frame row that corresponds to the player's angle of view
if sprite_frame_row == 8:
	sprite_frame_row = 0
var old_coords = sprite.get_frame_coords()
var old_x = old_coords.x
# Set the proper frame row to appear to face the correct direction
var new_coords = Vector2(old_x, sprite_frame_row)
sprite.set_frame_coords(new_coords)

Here's my sprite sheet if you'd like to try. It has 12 columns (vframes) and 8 rows (hframes).
NPC Mr Drizzlehop

When looping the animation player and walking around the sprite, you should see row 0 pop up for an instant every loop.

Minimal reproduction project

2023 07 09 8D Billboard Sprite Test.zip

@Calinou
Copy link
Member

Calinou commented Jul 9, 2023

@JonnyJive5 Can you try following the same steps on 4.1 dev/beta/RCs and see if the issue occurs? You can download them here.

@JonnyJive5
Copy link
Author

JonnyJive5 commented Jul 9, 2023 via email

@akien-mga
Copy link
Member

Yes it would be great if you could test subsequent snapshots to find the first one with the bug.

@JonnyJive5
Copy link
Author

JonnyJive5 commented Jul 11, 2023 via email

@akien-mga
Copy link
Member

akien-mga commented Jul 11, 2023

That's weird, I tested and I seem to have different results.

For me 4.1-dev3 is the first version where I see some invalid frames happened in the transition. To reproduce the issue, I move the camera a bit to the left to look at the character's profile, and its idle animation jitters frequently. In 4.0.3-stable or 4.1-dev2 it doesn't jitter.

Here's what I see in 4.1-dev3 and later:

simplescreenrecorder-2023-07-11_23.04.06.mp4

@akien-mga akien-mga added this to the 4.2 milestone Jul 11, 2023
@JonnyJive5
Copy link
Author

JonnyJive5 commented Jul 11, 2023 via email

@akien-mga
Copy link
Member

Yeah it's possible, 4.1-dev3 introduced #75901 which caused a number of regressions. This looks like one that could be caused by it, but will need the @godotengine/animation team and @RandomShaper to evaluate further when they're available.

@JonnyJive5
Copy link
Author

JonnyJive5 commented Jul 11, 2023 via email

@fire
Copy link
Member

fire commented Aug 21, 2023

@TokageItLab This is weird.

@RandomShaper
Copy link
Member

#75901 came with a little surprise in regards to the order in which nodes are processed. Details are in #78745, but in short, within the same process priority, each node has its internal processing run first, then its regular processing. Formerly, the internal processing of every node happened first, then the regular processing of all of them. We accepted this change. Let's say it was a change of an implementation detail to favor performance.

So, the MRP is relying on the fact that, on each frame, the AnimationPlayer will update frame first, then the script attached to the billboard sprite will run. The script would therefore be able to read the frame_coords value set by the player, alter its y component and set it again. After the change of processing order in Godot, that won't happen that way anymore. Since processing is organized by node first, the script will run first and then the AnimationPlayer will have its internal processing run (where it actually processes animations). The result is that frame_coords.y will be reset to 0 whenever the player updates the value, causing the glitch.

With the current perspective, we'd say that the MRP should stop relying on the order of processing that is not guaranteed within a processing group, and instead do something as simple as setting 8 D Billboard Sprite's process_priority to 1 (or AnimationPlayer's to -1!) so the engine is effectively instructed on what the user really wants.

All in all, the kind of approach in the MRP is dangerously close to the boundary of fighting the engine vs. using it. I'd suggest in any case an alternative approach; AnimatedSprite3D maybe?

I'll close as not-a-bug.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants