How to use the AtlasTexture2D with Polygon2D

Godot Version

4.2.1

Question

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.

The texture atlas looks like this:

For a Polygon2D node with texture, normally, I would go in the Sprite Editor and draw out the boundaries, like this:

Problem happens when I go to the Polygons tab, it doesn’t seem to follow the uv’s I set:

Similar in game it’s rendered like that:

image

1 Like

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.)

Did you find a solution to the issue?

Nope, just gave up on this for now.

Ah, that’s unfortunate.
Thanks for the quick response though!

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)