Problem with the pivot point of multiple sprites in AnimationPlayer

Godot Version

4

Question

` I created a body (Sprite2D). Then I created two animations for my AnimationPlayer. They’re two different spritesheets with different sizes. When I switch between them, they should be aligned perfectly with eachother.

The player’s head can be in different position due to different size of a different spritesheet, but I’d like to align it so that the pivot point is in the center of the head for every animation. This is necessary, so that when I move my cursor, the sprite doesn’t get rotated weirdly, but instead it looks like just the arms are rotating/spinning while the head is completely untouched.

The problem I’m facing is that both animations are attached to one Sprite2D (body) and when I fix the position for one animation, the other one is affected aswell.

How can I fix the positions of each animation separately, without affecting others? `

I think you would have to add some logic to adjust the offset of one of the sprite sheets when you switch to it.

much easier to just make all sprite sheets the same size

How can I do this? Lets say I switch from “idle” to “run” and now the “run” animation is the one that isn’t aligned properly

If the run animation is playing, you could offset the whole sprite plane’s position;
var current_animation = animation

var offset = Vector2.ZERO
if current_animation == "run":
    offset = run_offset

$AnimatedSprite2D.position += offset

or you could offset the AnimationSprite2D offset property

$AnimatedSprite2D.offset = offset

or even do it in the shader UVs

void fragment() {
if (is_running) {
offset = run_offset;
} else if (is_walking) {
offset = walk_offset;
}

vec2 adjusted_uv = UV + offset;
ALBEDO = texture(TEXTURE, adjusted_uv);

}

but then you have to pass shader parameters from your animated2d node(gdscript), to the shader

func update_shader_params():
var is_running = animation == “run”
var is_walking = animation == “walk” # Adjust based on your animation names

shader_material.set_shader_parameter("is_running", is_running)
shader_material.set_shader_parameter("is_walking", is_walking)

The first solution worked, thanks!

1 Like

Actually, I was wondering, is there any way to calculate mathematically what the offset for each different sprite should be, based on the first sprite’s width, height, offset and maybe position too? I really care about perfect alignment

Yea, I mean I’d have to see your set up to know how to really do it. I’m wondering what’s the value in using 2 different sprite sheets even, versus just 1 square that big enough for all animations, and then keep the head centered.

If the head is in a different position, I think you would have to define a 2d pivot for each animation state, and then offset by that for each animation

The biggest sprite frame size is 516 x 671, while most may be like 42 x 32. Some animations have up to 70 frames. And I have like 20 animations, so I think it would just be bad to load all that into memory at once, but maybe I’m wrong? I also think TexturePacker won’t let me create a single spritesheet with all those animations or even multiple spritesheets as big (which would need extra transparent canvas space to be the same size as the biggest sprite in my collection)

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.