I am using the AnimatedSprite2D to get an animation out of a AnimationFrames Resource. This resource is using a TextureAtlas. I want to make an animatable object that uses Skeleton2D node(only works with Polygon2D node).
So, I am taking an animation out of the TextureAtlas and putting it in the Polygon2D node. And now I am confused as to how it should work.
I’m having the same issue.
(In my case, I imported my textures via TexturePacker and had a plugin generate the texture atlas for me, but the end result is the same.)
Looking back at this, probably it could be solved with a shader. I guess thats how the shader does it probably. Eg. attach a shader to the polygon, read input from the texture atlas and change the uv to show the correct one.
Yup.
Here’s what I used. It’s still hard-codey. Can be made better:
Shader:
shader_type canvas_item;
uniform vec2 uv_offset = vec2(0, 0);
uniform vec2 uv_scale = vec2(0, 0);
void fragment() {
vec2 sampled_uv = uv_offset + (UV * uv_scale);
vec4 color = texture(TEXTURE, sampled_uv);
COLOR = color; // Output the final color
}
gdscript.
→ on the polygon2d
→ copy the rect x,y,w,h into Sprite Region Pixels
→ Atlas Size = size of the original image
extends Polygon2D
@export var atlas_size = Vector2(600,700)
@export var sprite_region_pixels: Rect2 = Rect2(247.0, 129.0, 73.0, 204.0):
set(value):
sprite_region_pixels = value
_update_shader_params()
var _shader_material: ShaderMaterial
func _ready()->void:
if not material is ShaderMaterial:
push_warning("Polygon2D material is not a ShaderMaterial. Cannot set atlas rect.")
return
_shader_material = material as ShaderMaterial
_update_shader_params()
func _update_shader_params():
if not _shader_material or not texture:
return
if atlas_size.x == 0 or atlas_size.y == 0:
push_warning("Atlas texture has zero size. Cannot calculate UVs.")
return
var uv_offset = Vector2(
sprite_region_pixels.position.x / atlas_size.x,
sprite_region_pixels.position.y / atlas_size.y
)
var uv_scale = Vector2(
sprite_region_pixels.size.x / atlas_size.x,
sprite_region_pixels.size.y / atlas_size.y
)
print("uv_offset ", uv_offset)
print("uv_scale ", uv_scale)
_shader_material.set_shader_parameter("uv_offset", uv_offset)
_shader_material.set_shader_parameter("uv_scale", uv_scale)