Complete Guide to Custom Animations in Roblox Studio — Animation Editor, Animator & AnimationTrack
TL;DR
Custom character animations in Roblox follow a three-step pipeline:
- Design the animation in the Animation Editor (keyframe poses on an R15 rig)
- Publish it to get an
rbxassetid:// - Play it in a script via
Animator:LoadAnimation()→AnimationTrack:Play()
If you're thinking of using TweenService for character movement — stop. TweenService animates object properties (Position, Color, Size…), not character joints. For actual character animation you need the Animator / AnimationTrack pipeline described below.
Part 1 — Setting Up Your Rig
Before touching a single keyframe, you need a poseable rig in your workspace.
The Animation Editor requires a rig, or poseable figure, to create character animations because rigs include the internal structure you need to move and rotate body parts into different poses.
R15 has 15 joints with full articulation, while R6 has only 6 — always use R15 for new projects.
To insert a test rig:
- Go to Plugins → Rig Builder
- Select R15 → Block Rig and insert it into Workspace
- Make sure the rig is selected before opening the Animation Editor
💡 You can also animate the actual player character from a
LocalScript, but it is cleaner to prototype on a static rig first.
Part 2 — Using the Animation Editor
The Roblox Animation Editor is more powerful than most developers realize — it supports full R15 body manipulation, inverse kinematics, custom easing curves, animation events, and direct publishing.
Opening the editor
Open the Animation Editor from the Plugins tab in Roblox Studio. You need a rig to animate — either use your game's character model or insert one from the Rig Builder. The interface shows a timeline at the bottom, a track list on the left (one track per joint), and a viewport where you pose the rig.
How keyframes work
Animation in Roblox works on a keyframe system. You set poses at specific time positions and the engine interpolates between them. To create a keyframe, scrub the timeline to your target time, then rotate or move a joint in the viewport — the editor automatically creates a keyframe for that joint at that time.
The Animation Editor lets you move and rotate your characters' body parts like an action figure into unique poses at different keyframes. Studio then automatically creates keyframes in between those poses that flow together to make your characters appear as if they're moving.
Workflow tips
- For smooth results, start with your key poses (the extremes of the motion) and then add breakdowns (intermediate poses that control the arc of movement).
- For a basic walk cycle, you need four key poses: contact, down, passing, and up. Place these at even intervals across the timeline, set the animation to loop, and refine from there.
- Use the play button in the Animation Editor to preview before publishing.
Publishing the animation
Click File → Save to Roblox. Roblox uploads it and gives you an asset ID: rbxassetid://XXXXXXXXXX. Copy that — you'll need it in your script.
Part 3 — Playing the Animation in a Script
The correct API chain
-- LocalScript inside StarterCharacterScripts
local Players = game:GetService("Players")
local player = Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local humanoid = character:WaitForChild("Humanoid")
-- Get the Animator inside the Humanoid
local animator = humanoid:WaitForChild("Animator")
-- Create an Animation instance and assign your published asset ID
local animation = Instance.new("Animation")
animation.AnimationId = "rbxassetid://YOUR_ANIMATION_ID_HERE"
-- Load → returns an AnimationTrack
local track = animator:LoadAnimation(animation)
-- Play it!
track:Play()
Key points:
- An
AnimationTrackcannot be created directly — it is returned by theAnimator:LoadAnimation()method. - The
LocalScriptwaits for the local player'sHumanoidto load, creates a newAnimationinstance with the properAnimationId, loads it onto the humanoid to get anAnimationTrack, and plays it withAnimationTrack:Play(). - If the humanoid belongs to a player character, animations should be loaded and played from that client. If the humanoid belongs to an NPC which the server has network ownership of, animations should be loaded and played from the server.
Useful AnimationTrack parameters
track:Play() accepts optional arguments:
track:Play(
fadeTime, -- blend-in time in seconds (default 0.1)
weight, -- blend weight (default 1.0)
speed -- playback speed multiplier (default 1.0)
)
-- Example: slow-motion attack, blend over 0.2 s
track:Play(0.2, 1, 0.5)
-- Stop with a fade
track:Stop(0.3)
-- Looping (or set it in the editor)
track.Looped = true
track:Play()
Part 4 — Animation Priorities (Critical!)
This is the part most beginners get wrong. When multiple animations run on the same rig at the same time, Roblox needs to know which one "wins" for each joint.
The Priority property sets the priority of an AnimationTrack. Depending on what this is set to, playing multiple animations at once will look to this property to figure out which keyframe poses should be played over one another. Properly set animation priorities allow multiple animations to be played without them clashing.
The 7 priority levels from lowest to highest:
| Priority | Typical Use |
|---|---|
Core | Default Roblox built-in animations |
Idle | Standing / breathing loops |
Movement | Walk, run, swim |
Action | Attacks, emotes, tool use |
Action2 | Override above |
Action3 | Override above |
Action4 | Highest user-defined level |
Roblox's default character animations, including catalog animation bundles, play at Core priority. So if you want a custom idle that replaces the default idle, set your animation to Idle. If you want an attack that overrides everything, use Action or higher.
When multiple AnimationTracks are played concurrently and affect the same animated joints, the tracks are evaluated in order from high to low priority per joint, while the total track weight sum remains less than 1.0. When the weight sum reaches or exceeds 1.0 for a joint, evaluation stops.
You can set priority in the Animation Editor (recommended), or override at runtime:
track.Priority = Enum.AnimationPriority.Action
track:Play()
Where two playing animations direct the target to move the same limb in different ways, the AnimationTrack with the highest priority will show. If both have the same priority, the weights of the tracks will be used to blend the animations.
Part 5 — Animation Events (Keyframe Markers)
You can fire Lua callbacks at specific points inside an animation using KeyframeMarkers — great for spawning hit effects, sounds, or particles mid-animation.
- In the Animation Editor, right-click a keyframe → Add Marker → name it (e.g.
"HitStart") - In your script:
track:GetMarkerReachedSignal("HitStart"):Connect(function()
-- spawn a hit particle, play a sound, deal damage, etc.
print("Hit marker reached!")
end)
track:Play()
This fires every time playback of an AnimationTrack reaches a keyframe that does not have the default name, letting you run code at predefined points in an animation set by keyframe names.
Common Pitfalls
- Using
Humanoid:LoadAnimation()directly — deprecated. Always go throughHumanoid.Animator:LoadAnimation(). - Playing animations from a server Script on a player character — causes replication issues. Use a
LocalScriptinStarterCharacterScripts. - Priority conflicts — if your animation doesn't show, a higher-priority animation is overriding it. Debug with
animator:GetPlayingAnimationTracks(). - Animation not loading — make sure the asset is published under the same account that owns the experience, or published publicly.
- Confusing
TweenServicewith animations — TweenService smoothly changes instance properties (doors, UI elements). It does not understand character rigs or joints.
FAQ
Q: Can I use animations from the catalog? Yes — grab the asset ID from the catalog URL and use it as your AnimationId. Make sure the asset is free or that you own it.
Q: Does this work with custom rigs? Yes, as long as the rig has a proper Motor6D hierarchy. The Animation Editor will list all available joints automatically.
Q: How many animations can play at once? No hard cap, but stop tracks you no longer need with track:Stop() to keep performance clean.
Q: R6 vs R15 — which for animation? R15 has 15 joints with full articulation, while R6 has only 6. R15 allows for far more expressive animations and is the standard for modern projects.
If you're looking for ready-made animation packs or character scripts to speed up your project, browse the GM Market marketplace — there are solid community assets that pair well with a custom animation setup.
Happy animating! Post your questions below 👇