How to make 2D rect animation using XML file

Hello, guys!!!
I’m need you’re help. Im trying to make game, like a Friday Night Funkin, but im can’t figure out, how make normal animation using XML file with this Image
Do you have any ideas?
(actually size of this image 1024x1024, but size before 8192x8192)

There XML file:
pinkie.xml (24.4 KB)

Do you mean with a ParticleEmitter Flipbook?

no, im mean 2D animation to ImageLabel

Perhaps this will help you

no it doesn’t help
im need help with this XML

It seems that your .xml file isn’t organized into panels. I’m not sure if that’s a big issue with what you’re trying to do.

what do you mean? im dont get it

it needs to be like symmetrical (like the “R” roblox logo images in this picture)

basically next to each other in a table

1 Like

If you look at the images in the link I sent about flipbooks it shows an example, like @Electrizing showed.
The images in your .xml file aren’t in a grid, they just seem to be thrown together.

I could be way off base though because I’ve never done anything like this.

Well first thing would probably be to split your xml file into different categories depending on what animation it should belong to. In your case it appears you have 11 so I’ll start out by writing all of those out.

Note that since you resized your image the rect size and offsets may not be pixel perfect.

Anyway we can do it by using a giant string pattern to match each of the lines to convert the XML stuff to a Lua table:

local xmlData = [[your XML file (truncated to make this not be a giant post)]]

local luaXMLData = {}

xmlData = xmlData:split('\n') -- split into separate lines so it's easier to work with

local function bulkToNumber(...: any) -- utility function for bulk converting entries to numbers
	local packedEntries = { ... }
	for index, entry in packedEntries do
		packedEntries[index] = tonumber(entry) or entry
	return unpack(packedEntries)

for _, line: string in xmlData do
	local spriteName, emoteName, emoteFrame, pixelStartX, pixelStartY, width, height, frameX, frameY, frameWidth, frameHeight = bulkToNumber(line:match('<SubTexture name="(%w+)%s(%a+)(%d+)"%sx="(%d+)"%sy="(%d+)"%swidth="(%d+)"%sheight="(%d+)"%sframeX="(%-?%d+)"%sframeY="(%-?%d+)"%sframeWidth="(%d+)"%sframeHeight="(%d+)"'))
	if not spriteName or not emoteName or not emoteFrame then -- this line isn't valid so continue
	local dataThisSprite = luaXMLData[spriteName]
	if not dataThisSprite then -- if sprite data doesn't exist for this sprite, make a new entry in luaXMLData
		luaXMLData[spriteName] = {}
		dataThisSprite = luaXMLData[spriteName]
	local emoteNameEntry = dataThisSprite[emoteName]
	if not emoteNameEntry then -- if emote data doesn't exist for this frame, make a new entry
		dataThisSprite[emoteName] = {}
		emoteNameEntry = dataThisSprite[emoteName]
	dataThisSprite[emoteName][emoteFrame + 1] = { -- we need to add 1 because XML uses 0-based indexing and Lua uses 1-based indexing
		topLeftCorner =, pixelStartY) / 8; -- because your XML file was generated for an 8096x file and we're working with a 1024x one, divide by 8
		size =, height) / 8;
		frameOffset =, frameY) / 8;
		frameSize =, frameHeight) / 8

print(luaXMLData) --[[
	table laid out as:
		[spriteName] = {
			[emoteName] = {
				[frameNumber] = {
					topLeftCorner = Vector2(x, y);
					size = Vector2(width, height);
					frameOffset = Vector2(frameX, frameY);
					frameSize = Vector2(frameWidth, frameHeight)

-- now that we have everything laid out we can start animating our sprite

local containingFrame ='Frame')
containingFrame.Position = UDim2.fromScale(0.5, 0.5)
containingFrame.AnchorPoint =, 0.5)
containingFrame.Parent = script.Parent

local imageLabel ='ImageLabel')
imageLabel.Image = 'rbxassetid://13373402216';
imageLabel.Parent = containingFrame

local animInfo = luaXMLData.pinkie.hello

while true do
	for i = 1, #animInfo do
		local animInfoThisFrame = animInfo[i]
		local frameSize = animInfoThisFrame.frameSize
		containingFrame.Size = UDim2.fromOffset(frameSize.X, frameSize.Y)
		local size = animInfoThisFrame.size
		imageLabel.ImageRectSize = size
		imageLabel.ImageRectOffset = animInfoThisFrame.topLeftCorner
		imageLabel.Size = UDim2.fromOffset(size.X, size.Y)
		local imageOffset = -animInfoThisFrame.frameOffset -- we want to inverse due to our hierarchy
		imageLabel.Position = UDim2.fromOffset(imageOffset.X, imageOffset.Y)

Thank you!
This is really useful!

1 Like

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