Error in user YAML: (<unknown>): found character that cannot start any token while scanning for the next token at line 4 column 3
---
## Features
- Supports both **looped** and **one-shot** animations
- `playLocked` system to prevent interruptions (e.g. Reload)
- Built-in **queue system** for chaining animations
- Real-time control with `setSpeed` and `setWeight`
- Callback support when animations finish
- Fully compatible with **Rojo workflows**
- Safe `destroy()` method to prevent memory leaks
- Designed for **FPS systems, characters, and ability systems**
---
Place the module inside your project:
ReplicatedStorage
└── replicated
└── libs
└── animationHandler
└── animationController.luau
- Your model must follow this structure:
Viewmodel / Character (Model)
├─ Humanoid
├─ HumanoidRootPart
└─ Animations (Folder)
├─ Idle
├─ Equip / Run
├─ Fire / Attack
├─ Reload / Jump
Important
- Animations must be
Animationinstances- Each must have a valid
AnimationId- Animator is created automatically
- The system scans the
Animationsfolder inside the model - All animations are loaded using
Animator:LoadAnimation() - Tracks are cached internally for fast access
- A smart system handles:
- smooth transitions (fade in/out) optional fade usage: fadeIn = 0 (disables the fade)
- animation conflicts
- queue execution
- Animations are accessed by name (string)
local AnimationController = require(
game.ReplicatedStorage.replicated.libs.animationHandler.animationController
)
local viewmodelOrCharacter = Model or Character
local anim = AnimationController.new(viewmodel)
if not anim then
error("Failed to create AnimationController")
endanim:play("Idle")
anim:play("Walk", {
fadeIn = 0.3,
speed = 1.2,
looped = true
})anim:playOnce("Fire")anim:playOnce("Equip", nil, function()
anim:play("Idle")
end)anim:playLocked("Reload", nil, function()
anim:play("Idle")
end)-- Will wait until reload finishes
anim:queue("Fire")AnimationController.new(model: Model)- Creates a new controller instance.
- Model must contain
HumanoidandAnimations.
:play(name: string, config?: table)- Plays looped animations.
- Will not restart if already playing.
:playOnce(name: string, config?: table, callback?: function)- Plays animation once and optionally runs callback when finished.
:playLocked(name: string, config?: table, callback?: function)- Locks the controller until animation finishes.
- Incoming requests are queued.
:queue(name: string, config?: table, callback?: function)- Adds animation to queue.
- Plays automatically when previous finishes.
:stop(name?: string, fadeTime?: number)- Stops specific animation or current one.
:stopAll()- Stops all animations, clears queue, unlocks controller.
:setSpeed(name: string, speed: number)- Adjusts animation speed.
:setWeight(name: string, weight: number, fadeTime?: number)- Adjusts blending weight.
:destroy()- Destroys all tracks and connections.
- Must be called when model is removed.
[PlayLocked: Reload]
↓
(LOCKED)
↓
[Queue: Fire]
[Queue: Inspect]
↓
Reload Ends
↓
Fire Plays
↓
Inspect Plays
anim:destroy()- Always destroy before removing the model.
- Prevent animation spam:
if os.clock() - lastFire > 0.1 then
anim:playOnce("Fire")
end- Use clean animation names:
Idle
Walk
Run
Fire
Reload
Inspect
- ❗ Always create the controller using the GONNABE USED / CLONED model, not the template.
-- Wrong
AnimationController.new(template)
-- Correct
local clone = template:Clone()
AnimationController.new(clone)- Pull requests and issues are welcome.
- For major changes, please open an issue first.