roblox-animations
Use when working with Roblox animation systems including playing, stopping, or blending animations on Humanoid characters or non-Humanoid models, handling AnimationTrack events, replacing default character animations, or debugging animation priority and blending issues.
What this skill does
# Roblox Animations Reference
## Core Objects
| Object | Purpose |
|---|---|
| `Animation` | Asset reference — holds `AnimationId` |
| `Animator` | Lives inside Humanoid or AnimationController; loads and drives tracks |
| `AnimationController` | Replaces Humanoid for non-character rigs |
| `AnimationTrack` | Returned by `LoadAnimation`; controls playback |
---
## Where to Run Animation Code
| Scenario | Script Type | Location |
|---|---|---|
| Local player character | `LocalScript` | `StarterCharacterScripts` |
| NPC / server-owned model | `Script` | Inside model or `ServerScriptService` |
> Never play player character animations from a `Script` — they will not replicate correctly to the local client.
---
## Loading and Playing Animations
```lua
-- LocalScript in StarterCharacterScripts
local character = script.Parent
local animator = character:WaitForChild("Humanoid"):WaitForChild("Animator")
local animation = Instance.new("Animation")
animation.AnimationId = "rbxassetid://1234567890"
local track = animator:LoadAnimation(animation)
track:Play() -- default fade-in (0.1s), weight 1, speed 1
track:Play(0.1, 1, 0.5) -- fadeTime, weight, speed
track:AdjustSpeed(1.5) -- change speed while playing
track:AdjustWeight(0.5, 0.2) -- weight 0.5, fade over 0.2s
track:Stop() -- default fade-out (0.1s)
track:Stop(0.5) -- fade out over 0.5s
```
---
## AnimationTrack Events
```lua
-- Fires after fade-out completes
track.Stopped:Connect(function()
print("Animation finished")
end)
-- Use :Once for one-shot cleanup
track.Stopped:Once(function()
cleanup()
end)
-- Fires when a named keyframe marker is reached
-- Marker names are set in the Roblox Animation Editor
track:GetMarkerReachedSignal("FootStep"):Connect(function(paramString)
playFootstepSound()
end)
```
---
## Looped vs One-Shot
| Property | Looped | One-Shot |
|---|---|---|
| `track.Looped` | `true` | `false` |
| Set in | Animation Editor (loop toggle) | Animation Editor |
| Override at runtime | `track.Looped = false` | `track.Looped = true` |
| Stops automatically | No — must call `track:Stop()` | Yes — after one cycle |
```lua
-- Force a looped animation to play once
track.Looped = false
track:Play()
track.Stopped:Once(function() print("Done") end)
```
---
## Animation Priority and Blending
Priority controls which tracks win on contested joints. Higher priority overrides lower.
```
Idle < Movement < Action < Action2 < Action3 < Action4 < Core
```
```lua
idleTrack.Priority = Enum.AnimationPriority.Idle
runTrack.Priority = Enum.AnimationPriority.Movement
attackTrack.Priority = Enum.AnimationPriority.Action
idleTrack:Play()
runTrack:Play() -- overrides idle on shared joints
attackTrack:Play() -- blends on top for joints it owns
```
Weight adjusts influence when two tracks share the same priority:
```lua
trackA:Play(0, 0.6) -- weight 0.6
trackB:Play(0, 0.4) -- weight 0.4 — blended on shared joints
```
---
## Humanoid vs AnimationController
### Humanoid (characters and humanoid NPCs)
```lua
local animator = character:FindFirstChildOfClass("Humanoid"):FindFirstChildOfClass("Animator")
local track = animator:LoadAnimation(animation)
track:Play()
```
### AnimationController (props, vehicles, creatures)
```lua
local controller = model:FindFirstChildOfClass("AnimationController")
local animator = controller:FindFirstChildOfClass("Animator")
if not animator then
animator = Instance.new("Animator")
animator.Parent = controller
end
local track = animator:LoadAnimation(animation)
track:Play()
```
---
## Replacing Default Character Animations
The `Animate` LocalScript in the character holds animation references. Modify its `AnimationId` values on CharacterAdded.
```lua
-- LocalScript in StarterCharacterScripts
local animate = script.Parent:WaitForChild("Animate")
local function replaceAnim(slotName, newId)
local slot = animate:FindFirstChild(slotName)
if slot then
local animObj = slot:FindFirstChildOfClass("Animation")
if animObj then animObj.AnimationId = newId end
end
end
replaceAnim("idle", "rbxassetid://111111111")
replaceAnim("run", "rbxassetid://222222222")
replaceAnim("jump", "rbxassetid://333333333")
replaceAnim("fall", "rbxassetid://444444444")
replaceAnim("climb", "rbxassetid://555555555")
```
Available slots: `idle`, `walk`, `run`, `jump`, `fall`, `climb`, `swim`, `swimidle`, `toolnone`, `toolslash`, `toollunge`.
---
## Stop All Playing Animations
```lua
local function stopAll(animator, fadeTime)
for _, track in animator:GetPlayingAnimationTracks() do
track:Stop(fadeTime or 0.1)
end
end
```
---
## Quick Playback Reference
```lua
track:Play(fadeTime, weight, speed)
-- fadeTime default 0.1 — blend-in seconds
-- weight default 1.0 — joint influence (0–1)
-- speed default 1.0 — playback rate
track.TimePosition -- current position in seconds (read/write)
track.Length -- total duration in seconds
track.IsPlaying -- bool
track.Looped -- bool (override allowed at runtime)
track.Priority -- Enum.AnimationPriority
track.WeightCurrent -- actual blended weight right now
track.WeightTarget -- target weight after fade
```
---
## Upper-Body Only Animations
Priority blending affects **all joints** an animation touches. To play a wave only on the arms while legs animate from run/idle, the animation itself must be authored to only key upper-body bones (leave lower-body joints unkeyed in the Animation Editor). There is no runtime API to mask joints — the solution is in the animation asset, not the script.
---
## Common Mistakes
| Mistake | Fix |
|---|---|
| Playing character animations in a `Script` | Use `LocalScript` in `StarterCharacterScripts` |
| `LoadAnimation` called on `Humanoid` (deprecated) | Call on `Animator` instead |
| Two animations fighting on same joints | Assign different `Priority` values |
| `Stopped` fires immediately | Animation has zero length or wrong `Looped` setting |
| `GetMarkerReachedSignal` never fires | Marker name misspelled, or animation not re-uploaded after adding markers |
| NPC animation not visible to other clients | Play from a `Script` (server), not `LocalScript` |
| `AnimationController` track won't play | Missing `Animator` child inside `AnimationController` |
Related in General
modeling-omnistudio-epc-catalog
IncludedSalesforce Industries CME EPC product-modeling skill for Product2-based catalog creation. Use when creating EPC products, configuring product attributes, building offer bundles with Product Child Items, or reviewing EPC DataPack JSON metadata for product catalog changes. TRIGGER when: user creates or updates Product2 EPC records, AttributeAssignment payloads, AttributeMetadata/AttributeDefaultValues, Offer bundles, or ProductChildItem relationships. DO NOT TRIGGER when: designing OmniScripts/FlexCards/Integration Procedures (use building-omnistudio-omniscript, building-omnistudio-flexcard, or building-omnistudio-integration-procedure), implementing Apex business logic (use generating-apex), or troubleshooting deployment pipelines (use deploying-metadata).
relationship-science-coach
IncludedUse this skill for direct, practical adult relationship coaching: couples conflict, repair, trust, marriage, dating, flirting, attachment patterns, emotional connection, sex, desire differences, eroticism, kink negotiation, affection, love languages, breakups, and long-term passion. Draw on Gottman, EFT and Hold Me Tight, attachment science, modern sex research, Perel, Nagoski, Kerner, Schnarch, Love and Stosny, and flexible love-language tools. Be concrete and low-hedge. Redirect only for imminent danger, abuse, coercive control, minors, non-consent, self-harm, stalking, or medical/legal/psychiatric decisions.
building-sf-integrations
IncludedSalesforce integration architecture and runtime plumbing with 120-point scoring. Use this skill to set up Named Credentials, External Credentials, External Services, REST/SOAP callout patterns, Platform Events, and Change Data Capture. TRIGGER when: user sets up Named Credentials, External Services, REST/SOAP callouts, Platform Events, CDC, or touches .namedCredential-meta.xml files. DO NOT TRIGGER when: Connected App/OAuth config (use configuring-connected-apps), Apex-only logic (use generating-apex), or data import/export (use handling-sf-data).
venue-templates
IncludedAccess comprehensive LaTeX templates, formatting requirements, and submission guidelines for major scientific publication venues (Nature, Science, PLOS, IEEE, ACM), academic conferences (NeurIPS, ICML, CVPR, CHI), research posters, and grant proposals (NSF, NIH, DOE, DARPA). This skill should be used when preparing manuscripts for journal submission, conference papers, research posters, or grant proposals and need venue-specific formatting requirements and templates.
let-fate-decide
IncludedDraws the 12 Houses of the Zodiac Tarot spread to inject entropy into planning when prompts are vague, ambiguous, or casually delegated. Interprets the spread to guide next steps. Use when the user says 'let fate decide', 'YOLO', 'whatever', 'idk', or other nonchalant phrases, makes Yu-Gi-Oh references, or when you are about to arbitrarily pick between multiple reasonable approaches. Prefer over ask-questions-if-underspecified when the user's tone is casual or playful rather than precision-seeking.
net-ops
IncludedCross-platform network troubleshooting (Windows, macOS, Linux) via local or remote shell. Use for: DNS broken, can't resolve hostnames, nslookup/dig works but apps fail, NRPT, WFP, scutil, /etc/resolver, systemd-resolved, /etc/resolv.conf, NetworkManager, VPN DNS leak residue (ProtonVPN/Mullvad/WireGuard/AnyConnect), AV/firewall blocking DNS or DoH, Tailscale DNS interaction, intermittent connectivity, remote diagnostics over SSH.