Get animation frames of sprite at runtime

I can use go.get("#sprite", "image") to get the ID of an atlas, but is there a way to get individual images from that atlas?

These textures are generated, and I want to use their IDs as keys to a table to get texture specific data from. I can’t split these into separate atlas files, because I’m playing flipbook animations.

Yes, you can use resource.get_atlas():

1 Like

The texture property of this data seems to contain all images on the atlas. I can have the same atlas on two different objects with two different animations, but I get the same texture ID from get_atlas.

Is there a way to get animation frames from the atlas instead of the entire texture?

The table you get from resource.get_atlas() should give you all meta data about the atlas: the texture, the geometries, and the animations.

Try printing the table with pprint(t)

1 Like

I see now that I can get vertex and UV data from the texture to get the image data I want, but how do I figure out what the current animation frame is using this data?

I could use the texture ID and the geometry index, but sometimes my animations will reuse images, so they don’t map perfectly.

To clarify, I’m using sprite.play_flipbook to play animations, and I want to know which frame is currently being used in the animation. This is because I have colour data that I want to apply to the image through a shader, but that colour data changes depending on the frame.

I think I figured it out, and I don’t think I need atlas data at all… Will get back to this thread tomorrow once I give this a shot and I’ll share my findings.

We currently do not have a frame index property (we should imho), so for now you have to calculated it using the cursor property and your animation length.

1 Like

My code almost works:

-- update
local anim_id = go.get(SMALL_SPRITE_URL, "animation")
local cursor = go.get(SMALL_SPRITE_URL, "cursor")

local frame_count = get_current_frame_count(anim_id)
local current_frame_number = math.ceil(cursor * frame_count)
local function get_current_frame_count(anim_id)
	local atlas = go.get(SMALL_SPRITE_URL, "image")
	local atlas_data = resource.get_atlas(atlas)

	for k, v in ipairs(atlas_data.animations) do
		if hash(v.id) == anim_id then
			return v.frame_end - v.frame_start
		end
	end
end

It gets the correct frame number most of the time, but it’s off by maybe 1 game tick, meaning the animation frame changes, and the frame number is corrected the following frame. I don’t know how to properly debug this, but the frame number is not accurate 100% of the time.

2 Likes

Is there anything that stands out as weird in this code that would cause it to render 1 frame late? And how would one debug this situation? The code is almost right but it’s still unusable.