SpriteSheetManager

:jigsaw: SpriteSheetManager β€” GUI Sprite Sheet Animator

A fully modular image-based sprite sheet animator designed for UI animations with maximum flexibility and minimal effort.

:package: Get the module on Creator Marketplace

Inspired by this post by @HungryHungryFox02.
Special thanks to ChatGPT for writing every single line of code. :upside_down_face:


:dart: Features

:white_check_mark: Regular loop
:white_check_mark: Bounce (ping-pong) loop
:white_check_mark: Frame skipping
:white_check_mark: Manual direction
:white_check_mark: Reversible play
:white_check_mark: Runtime FPS control
:white_check_mark: Pause, resume, stop
:white_check_mark: Event-driven architecture
:white_check_mark: Lock row/column playback

No external dependencies. Plug & play.


:rocket: Quick Start

local SpriteSheetManager = require(path.to.SpriteSheetManager)

local manager = SpriteSheetManager.new({
	ImageLabel = script.Parent.ImageLabel,
	Frames = 16,
	Rows = 4,
	Columns = 4
})

manager:Play()

πŸ—οΈ Full Constructor Options
local manager = SpriteSheetManager.new({
	ImageLabel = yourImageLabel,
	Frames = 12,
	Rows = 3,
	Columns = 4,
	FPS = 24,
	isLooped = true,
	isBounceLooped = false, -- isBounceLooped will override isLooped
	InitialFrame = 1, -- initial frame will overrite (initial) row and column
	InitialRow = 1,
	InitialColumn = 1,
	IgnoreFrames = {2, 4},
	IgnoreRows = {3},
	IgnoreColumns = {1},
	isOneDimensional = false,
	isTopToBottom = false -- this will only work if isOneDimensional is true
})

:video_game: Controls

manager:Play()
manager:Pause()
manager:Resume()
manager:Stop()
manager:ReversePlay() -- changes direction before calling Play()

manager:SetFPS(15)
print(manager:GetFPS())

manager:SetFrame(6)
print(manager:GetFrame())

manager:SetDirection(-1)
print(manager:GetDirection())

πŸ”’ Locking Playback (Row/Column)
manager:LockRow(3)      -- Locks given row, plays across columns
manager:LockColumn(3)   -- Locks given column, plays across rows
manager:ClearLock()    -- Unlocks both

:satellite: BindOns

Use :BindOnX() to bind functions on Events.

manager:BindOnFrameChanged(function(frame)
	print("Frame:", frame)
end)

manager:BindOnBounceReversed(function()
	print("Direction:", manager:GetDirection())
end)

manager:OnStopped(function()
	print("Stopped at:", manager:GetFrame())
end)
Event Name When it Fires
FrameChanged On every visible frame update
Paused When Pause() is called
Resumed When Resume() is called
Stopped When animation is stopped
Looped On a normal loop wraparound
BounceReversed Direction flips in bounce mode

:bar_chart: State Check

print(manager:GetState())    --> "Playing" | "Paused" | "Stopped"
print(manager:isPlaying())   --> true/false
print(manager:isPaused())    --> true/false
print(manager:isStopped())   --> true/false

:gear: Requirements

  • Sprite sheet must be evenly spaced (grid).
  • Target must be ImageLabel.
  • Recommended ScaleType = Crop on ImageLabel.
  • For previewing in studio, change ImageLabel size property to match Size = UDim2.fromScale(columns, rows).

:no_entry: Limitations

  • :zap: FPS was previously capped at 60 β€” now unlimited!
  • Do not enable both isLooped and isBounceLooped at the same time.
  • Do not enable both Row and Column Lock at the same time.
  • Works only with ImageLabel (no ImageButton, etc.)
  • Ensure consistent layout for accurate animations.
  • Frames, Rows, Columns count must entered by hand.

:test_tube: Sample Setup

Example: UI Button with Sprite Animation
local SpriteSheetManager = require(path.to.SpriteSheetManager)

local button = script.Parent.ImageLabel
local animator = SpriteSheetManager.new({
	ImageLabel = button,
	Frames = 20,
	Rows = 5,
	Columns = 4,
	FPS = 16,
	isBounceLooped = true
})

button.MouseEnter:Connect(function()
	animator:Play()
end)

button.MouseLeave:Connect(function()
	animator:Stop()
end)

Got feedback or suggestions? Drop them below!
Enjoy animating! :art::sparkles:

:package: Get the module on Creator Marketplace

6 Likes

Why would it be. The FPS is capped by whatever limitation your GPU has or game setting

3 Likes

Much thanks to my king: ChatGPT.

7 Likes

The source in the link I wrote as inspired by is old, perhaps it was necessary in the past, but I didn’t really think much about it. I worked on it for 12 hours after creating a 15-frame animation, so it’s not a big deal for me. If deleting it isn’t a problem, I can delete it.
wise words from the legend~~

2 Likes

So is this just slop AI code from chatgpt?

4 Likes

So real. I love making AI write modules for me.

1 Like

β€œthanks to chatgpt writing every line of code”

yeah i wont be using this

1 Like