Claude Skill

roblox-animation

Build or debug Roblox character animations, IK poses, animation-marker events, and UI or object tweens. Use for locomotion, emotes, motion blending, and timed effects.

LLM Mart · 0 points · 0 views 0 listing impressions 0 install-command copies
Virus-scanned Reviewed automatically before listing.

Full trust report

Download nonlooped-roblox-suite-roblox-animation-2904c16.zip · 16 KB
Part of nonlooped/roblox-suite — 15 skills

Install

skills CLI npx skills add https://github.com/nonlooped/roblox-suite/tree/main/roblox-animation
Claude Code claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install nonlooped-roblox-suite@llmmart
Git git clone https://github.com/nonlooped/roblox-suite.git

The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole nonlooped/roblox-suite collection as a plugin from our marketplace. Git is the plain clone.

Skill manifest

roblox-animation

Choose animation tracks for authored rig motion, TweenService for property changes, and IKControl for procedural poses. Validate gameplay outcomes on the server even when a client animation triggers the visual effect.

Key official sources:

Cross-skill usage:

  • Combine with roblox-user-interfaces for UI motion details and "particles in UI".
  • Combine with roblox-vfx when animations should trigger emitters, beams, or trails via markers.
  • Combine with roblox-core for Animator acquisition, RunService timing, and preloading via ContentProvider.
  • Use roblox-networking to decide where to play/ control animations (server replication vs client-only cosmetics).

Choose a motion system

3D rig/character motion that needs to look authored and blendable?
→ Animation system (Animator + AnimationTrack). Pre-authored in Editor or from catalog, played with priority/weight/fade/speed. Drive gameplay from markers.

Simple property changes, UI transitions, or one-off object motion?
→ TweenService. Use for GuiObjects (scale + AnchorPoint + UDim2), CFrame, Color3, Transparency, NumberSequence, etc.

Need procedural interaction with environment (hand reaching, head tracking, foot placement on uneven ground)?
→ IKControl (procedural) + optional AnimationTracks or constraints for limits. Often combined with animation events.

Combining systems: Play a locomotion track on low priority while using IKControl or tweens for upper-body or UI overlays. Use markers in the track to start/stop IK or fire tweens/effects.

See references/3d-animations.md and references/ui-tweens-and-sequences.md for details.

Rig animations and IK

Read 3d-animations.md when authoring, loading, or blending rig animations, or configuring IK.

  • Load tracks through Animator. Choose priority, weight, fade time, and speed for the action.
  • Use named markers for footsteps, effects, and other timed events. Keep names stable when republishing assets.
  • Decide where playback runs and check asset ownership. Validate gameplay effects on the server.
  • Preload Animation assets and reuse loaded tracks. Stop tracks and disconnect their signals when the rig is removed.
  • For IK, define the chain root, end effector, and target. Tune responsiveness and joint limits in Play mode.

UI animation with TweenService

Read ui-tweens-and-sequences.md for property examples, easing, chained transitions, and typewriter text.

Use scale and AnchorPoint for responsive motion, and add an aspect-ratio constraint when the design requires fixed proportions. Use CanvasGroup for whole-panel fades. Cancel conflicting tweens and disconnect completion handlers when a sequence ends or its GUI is destroyed.

For text reveal, use TextLabel.MaxVisibleGraphemes and account for localization and Unicode character boundaries.

Combine motion with other systems

  • Animation markers → everything else: Footstep marker → play sound + emit particle at foot Attachment. Attack marker → enable hitbox or IK reach + spawn muzzle flash. "AbilityStart" marker → start a Tween on a UI cooldown ring or BillboardGui.
  • Priorities + weight for layering: Idle (low) + Walk (medium) + Action (high, weight 1.0 with fade). Use AdjustWeight and AdjustSpeed at runtime.
  • Client vs Server playback: For a player's own character, animations played on the client replicate to the server via the Animator (subject to ownership/permissions); for NPCs and other characters, the server is the authority. Cosmetic or prediction-friendly animations can be client-only. Gameplay-affecting timing (damage windows, movement locks) should be validated server-side; do not treat client markers as authoritative proof of a hit.
  • Preload + cache tracks: Load once per rig type, reuse the AnimationTrack objects. Use AnimationClipProvider for async animation loading when you need previews or streaming behavior.
  • UI + 3D harmony: Tween a 3D part or Attachment while a BillboardGui or SurfaceGui on it also tweens (or uses ViewportFrame for embedded 3D previews with parts/meshes/cameras; note that ParticleEmitters/Beams/Trails/Lights do not render inside ViewportFrame).
  • Testing: Different devices have different frame rates and input latency. Test easing feels on mobile + desktop. Use MicroProfiler for heavy simultaneous tweens.

Common mistakes

  • Humanoid:LoadAnimation(anim) (deprecated; use Animator).
  • Polling track.TimePosition every frame instead of markers.
  • Tweening raw pixel offsets instead of scale + AnchorPoint (breaks on resolution/aspect changes).
  • Playing high-priority actions without fade time (jarring).
  • Never preloading (first play hitch).
  • Using the same low AnimationPriority for everything (idles fighting actions).
  • Ignoring IK constraints (elbows/knees bending backwards, wrists at impossible angles).
  • Tweening dozens of individual UI elements instead of using CanvasGroup or layouts.

Examples and verification

Adapt AnimationLoader.lua, TweenHelper.lua, or IKSetup.lua when the helper fits the task.

For a changed animation, verify that it plays at the intended priority, fires its markers, and cleans up when the rig is removed. For UI motion, check the target screen sizes and cancellation path. Use integration-and-events.md when motion drives another system.

Reference index

Files (roblox-suite)
  • references
    • 3d-animations.md 11 KB
      ---
      read_when: "Author or load rig animations, blend tracks, or configure IK"
      last_reviewed: 2026-06-17
      ---
      
      # 3D animations (rigs, animator, tracks, IK, editor)
      
      **Core docs:** https://create.roblox.com/docs/animation + editor + inverse-kinematics + events
      
      ## Rigs and the animation system
      
      A "rig" is a model whose parts or bones are connected in a hierarchy that the animation system can drive (historically Motor6D joints, now also AnimationConstraint + Bones).
      
      Roblox provides:
      - R15 / Rthro standard characters: Rthro uses the R15 skeleton with modified proportions, so it remains compatible with catalog and default animations.
      - Rig Builder tool for quick test rigs.
      - Custom imported skinned/boned meshes with proper bone hierarchy.
      
      At runtime, every animatable model needs an **Animator** instance (child of Humanoid for characters, or under an AnimationController for non-Humanoid rigs). The Animator is responsible for loading, playing, blending, and replicating animation state.
      
      Legacy `Humanoid:LoadAnimation` is deprecated. Always go through the Animator.
      
      ## Authoring in the Animation Editor
      
      1. Select a rig in the viewport or Explorer.
      2. Open Animation Editor (Window > Animation Editor).
      3. The interface has:
         - Playback controls + name + looping toggle + priority selector.
         - Track list (bones/meshes that have keyframes).
         - Timeline with scrubber (seconds:frames at 30 fps default; adjustable).
      
      **Creating poses:**
      - Move the scrubber.
      - Select a bone or mesh.
      - Use Move (or press R for Rotate) to pose it.
      - A keyframe is automatically created on that track at the scrubber time.
      - Repeat for multiple poses across time.
      - Play/scrub to preview. The editor interpolates between keyframes.
      
      **Keyframes operations:**
      - Right-click timeline or keyframes for Add Keyframe, Delete, Duplicate (copy/paste), etc.
      - Drag keyframes to retime.
      - Right-click keyframe → Easing Style (Linear, Constant/snap, CubicV2, Elastic, Bounce) and Easing Direction (In, Out, InOut).
      - Constant style removes interpolation (useful for mechanical or hit reactions).
      
      **Optimization:**
      - Editor auto-removes redundant identical consecutive keyframes in some cases (facial, curve promotion).
      - Manual "Optimize Keyframes" tool (⋯ menu) lets you reduce count while previewing.
      
      **Looping:**
      - Toggle the Looping button.
      - For seamless loops, duplicate the first keyframe(s) and place them at the end.
      
      **Priorities (set in editor or on track at runtime):**
      Core < Idle < Movement < Action < Action2 < Action3 < Action4 (highest).
      Higher priority animations take precedence in blending.
      
      **Events / Markers (critical for gameplay sync):**
      - Click the settings icon on timeline → Show Animation Events.
      - Scrub to desired time, click Edit Animation Events → + Add Event, give it a name (and optional parameter string).
      - At runtime: `track:GetMarkerReachedSignal("FootStep"):Connect(function(paramString) ... end)`
      - The parameter is a string you can parse (e.g. "left,heavy" or a JSON-like value).
      - Duplicate events across the timeline for recurring actions (multiple footfalls).
      
      **Saving vs Exporting/Publishing:**
      - Save / Save As → stores a KeyframeSequence (or CurveAnimation) locally under the rig in ServerStorage (for iteration). Not replicated.
      - Publish to Roblox → makes it a reusable asset with an ID that works in any experience (and group-owned if you choose the creator).
      - For default character animation replacement, the final keyframe **must** be named exactly "End" (case sensitive) before publishing.
      
      **Accessing local saves in rare cases:**
      The rig gets an AnimSaves folder with an ObjectValue pointing at the saved data. Do not rely on this for gameplay. Publish and use asset IDs.
      
      ## Runtime playback (modern)
      
      ```lua
      local Players = game:GetService("Players")
      local ContentProvider = game:GetService("ContentProvider")
      local ReplicatedStorage = game:GetService("ReplicatedStorage")
      
      local player = Players.LocalPlayer
      local character = player.Character or player.CharacterAdded:Wait()
      local humanoid = character:WaitForChild("Humanoid")
      
      -- Player characters have an Animator created by the engine on the server. Wait for it so replication works.
      -- Custom rigs / NPCs may need fallback creation.
      local animator = humanoid:FindFirstChildOfClass("Animator")
          or humanoid:WaitForChild("Animator", 1)
      if not animator then
          animator = Instance.new("Animator")
          animator.Parent = humanoid
      end
      
      -- Cache the Animation instance; Animator:LoadAnimation caches the returned track
      -- when called with the same Animation object on the same Animator.
      local anim = ReplicatedStorage:FindFirstChild("MyAnimation") or Instance.new("Animation")
      if not anim.AnimationId then
          anim.AnimationId = "rbxassetid://1234567890"
          anim.Name = "MyAnimation"
          anim.Parent = ReplicatedStorage
      end
      
      -- Preload asset instances (Animation, Sound, Decal, etc.). AnimationTracks are not valid here.
      ContentProvider:PreloadAsync({anim})
      
      local track = animator:LoadAnimation(anim)
      track.Priority = Enum.AnimationPriority.Action
      track.Looped = false
      
      track:Play(0.1, 1.0, 1.0)  -- fadeTime, weight, speed
      
      -- React to markers; store and disconnect connections on cleanup.
      local markerConn = track:GetMarkerReachedSignal("Impact"):Connect(function(param)
          -- e.g. spawn effect at a specific attachment, apply damage if server-validated, etc.
          task.defer(function() ... end)
      end)
      
      local endedConn = track.Ended:Connect(function()
          -- animation finished moving the rig
      end)
      
      local stoppedConn = track.Stopped:Connect(function()
          -- cleanup / state tracking
          markerConn:Disconnect()
          endedConn:Disconnect()
          stoppedConn:Disconnect()
      end)
      ```
      
      **`KeyframeReached` is an older event; prefer `GetMarkerReachedSignal` for all new work.**
      
      **Useful track methods/properties:**
      - Play / Stop / AdjustSpeed / AdjustWeight
      - Speed (current), TimePosition, Length, IsPlaying, WeightCurrent/Target
      - Priority (can be changed at runtime)
      - Stopped, Ended, DidLoop, `GetMarkerReachedSignal` (preferred), `KeyframeReached` (legacy; avoid for new work)
      
      **Track caching:** Calling `Animator:LoadAnimation` with the same `Animation` instance on the same `Animator` returns the same `AnimationTrack` object. This is useful for stopping or reusing a track, but be careful about conflicting Play calls with different fade/weight settings.
      
      **Async loading with AnimationClipProvider:** For previews, streaming, or loading large animations without blocking, use `AnimationClipProvider:LoadAnimationClipAsync(animationAssetId)` to obtain a temporary `AnimationClip`, then assign it to an `Animation` instance's `AnimationId` or pass it to `Animator:LoadAnimation` when supported.
      
      **Ownership and replication permissions:** For a client-played animation on the player's own character to replicate to the server, the animation asset must be owned by the player or by the experience/creator. If the asset is owned by another player or group, the server will not replicate it. NPCs and other characters should have animations played from the server for authority.
      
      **Cleanup patterns:** Stop tracks and disconnect marker/Ended/Stopped connections on `Humanoid.Died` or when the character is removed. For LocalScripts, listen to `player.CharacterRemoving` or the rig's `AncestryChanged`.
      
      ```lua
      humanoid.Died:Connect(function()
          track:Stop(0.1)
          markerConn:Disconnect()
          endedConn:Disconnect()
          stoppedConn:Disconnect()
      end)
      ```
      
      **Blending notes:**
      Multiple tracks can be active. The engine blends poses according to priority and current weights. Use weight < 1.0 for partial overlays (e.g. upper body aim while running).
      
      ## IKControl for procedural animation
      
      Add an `IKControl` under the Humanoid (or AnimationController).
      
      **Required properties:**
      - Type (`Position`, `Transform`, `Rotation`, `LookAt`, etc.; Enum.IKControlType)
      - EndEffector (the Bone or BasePart that should reach the target, e.g. LeftHand)
      - Target (any object with a world position; Attachment is convenient for testing)
      - ChainRoot (the highest joint in the chain that should be affected, e.g. LeftUpperArm for a full arm reach)
      
      **Tuning:**
      - `P`: higher values make the IK more responsive (can overshoot); lower values are smoother.
      - `SmoothTime`: how quickly the effector interpolates toward the target; useful for dampening noise.
      - Use these together to balance snappiness and stability, especially for head tracking or foot planting.
      
      **Adding natural limits with Constraints:**
      - Create a HingeConstraint (or BallSocketConstraint) with the same parent Model as the IKControl.
      - Create matching Attachments on the relevant parts (elbow, wrist, etc.).
      - Place constraint attachments at the same joint locations represented by the Motor6D C0/C1 offsets, so limits align with the rig's natural pivot.
      - For Hinge: rotate the PrimaryAxis attachment to the correct bend axis.
      - For BallSocket on wrist: enable LimitsEnabled and set a reasonable UpperAngle (e.g. 80°).
      - Test live: you can create/edit IKControls and constraints during a Play session.
      
      Use IK for:
      - Hand reaching for interactive objects (doors, levers, pickups).
      - Head/eyes tracking a point of interest.
      - Feet adjusting to uneven terrain or steps (more advanced setups).
      
      Combine with animation tracks: play a "reach" animation at high priority while an IKControl is active, or use markers to enable/disable specific IKControls.
      
      ## Curve animations
      
      You can promote a keyframe animation to a curve animation in the editor for per-channel (position/rotation per bone) curve editing. This gives finer artistic control than discrete keyframes.
      
      ## Performance and best practices
      
      - Preload Animation asset instances, not AnimationTracks.
      - Cache and reuse Animation instances; `Animator:LoadAnimation` caches tracks when called with the same Animation on the same Animator.
      - Stop and clean up tracks and connections when the character is removed or dies.
      - For replicated characters, understand authority: the client's own character can play animations that replicate via the Animator (subject to asset ownership), while NPCs/other characters are usually server-authoritative.
      - Validate gameplay side-effects from markers on the server; use `task.defer` inside marker handlers to avoid stalling the animation evaluator.
      - High numbers of simultaneous complex animations + particles + UI can be expensive. Profile.
      - Markers are far more efficient and maintainable than polling TimePosition every frame.
      
      ## Common pitfalls
      
      - Using the deprecated Humanoid:LoadAnimation path.
      - Forgetting to set final keyframe name to "End" when replacing default animations.
      - Playing everything at Action priority (or Core) so nothing blends correctly.
      - No fade time on Play/Stop (jarring pops).
      - Relying on local ServerStorage saves for anything that needs to replicate or persist across sessions.
      - IK without constraints (unnatural joint hyperextension).
      - Not testing on actual R15 characters vs custom rigs.
      - Trusting client markers as authoritative proof of hits; always validate distance, stance, and timing server-side.
      - Preloading AnimationTracks instead of Animation asset instances.
      
      For the most current property details or new IKControlType values, always cross-reference the live Engine API reference.
      
    • integration-and-events.md 6.5 KB
      ---
      read_when: "Synchronize animation markers with gameplay, effects, audio, or UI"
      last_reviewed: 2026-06-17
      ---
      
      # Integration, events, priorities, and cross-system patterns
      
      ## Marker-driven events
      
      Use `GetMarkerReachedSignal("MarkerName")` to trigger events at authored times. Prefer it over polling `track.TimePosition` or using the older `KeyframeReached` event.
      
      Examples of what you can drive purely from authored markers:
      - Footstep sounds + dust ParticleEmitter at the correct foot Attachment.
      - Enable/disable hitboxes or damage volumes exactly when the swing "connects".
      - Spawn muzzle flash, shell ejection, or impact VFX.
      - Trigger camera shake, screen flash, or UI hit markers.
      - Start a secondary animation or IKControl (e.g. "grab" a prop at a specific frame).
      - Play ability VFX or BillboardGui popups synchronized to the animation.
      
      The parameter string on the marker is free-form text you control in the editor. Many teams use a simple convention like "leftFoot,heavy" or even small JSON strings that the connected function parses.
      
      Inside marker handlers, keep work small and use `task.defer` for gameplay side-effects to avoid stalling the animation evaluator.
      
      Because markers are part of the published animation asset, designers can retime or add new events without a programmer touching code (as long as the string names stay stable or are versioned).
      
      ## Priority and weight layering
      
      Do not put everything at Action priority.
      
      Typical layering for a character:
      - Core (engine defaults, facial, etc.)
      - Idle (breathing, subtle shifts)
      - Movement (walk, run, strafe; these often blend with each other)
      - Action (attacks, emotes, interact, abilities; these usually want to fully or mostly override lower layers)
      
      You can play a low-weight "aim" or "upper body" track at Action priority while a walk/run continues at Movement. Use `track:AdjustWeight(0.6)` and `AdjustSpeed(...)` at runtime for fine control (e.g. variable walk speed affecting animation rate).
      
      When a higher priority track starts with a fade time, the engine cross-fades the weights smoothly.
      
      ## Server vs client playback decisions
      
      - **Authority matters:** For a player's own character, animations played on the client replicate to the server through the Animator (the asset must be owned by the player or the experience). For NPCs and other players' characters, the server is usually the authority.
      - **Server playback** (recommended for gameplay state): The AnimationTrack runs on the server and state replicates to clients. Good for synchronized attacks, movement abilities, etc. Server can also validate timing via markers or TimePosition if needed.
      - **Client playback**: Purely visual or predictive (cosmetic emotes while moving, client-side reload animations, UI-driven preview animations). Cheaper and more responsive for pure eye candy. The server still needs to know the *intent* and results via Remotes.
      - **Ownership/permissions:** An animation asset must be owned by the player or the experience/creator for a client-played animation on that player's character to replicate. If ownership is wrong, the server will ignore it.
      
      For predictive playback, the client starts the animation immediately. The server runs the authoritative version, and the client corrects or blends if the server disagrees.
      
      **Important:** Markers are timing hints, not authoritative proof. Any gameplay effect (damage, hit registration) must be validated server-side using distance, stance, timing windows, stamina, etc.
      
      ## Combining with other systems
      
      **Particles / VFX (see roblox-vfx skill):**
      - Best pattern: Animation marker → in the connected function, find an Attachment on the rig (or create a temporary one) and either :Emit() on a pre-placed ParticleEmitter or parent a one-shot emitter.
      - You can also tween properties on an emitter (Rate, Speed, etc.) from a marker if you want the effect to ramp up or change character during the animation.
      
      **UI (see roblox-user-interfaces skill):**
      - Markers or track events can start UI tweens (cooldown rings, ability icons lighting up, hit number popups).
      - Conversely, a UI button press can start a 3D animation track (with proper server validation for gameplay actions).
      - ViewportFrames inside UI can contain their own rigs playing tracks or being driven by IK: this is how many 3D item previews or emote selectors work.
      
      **Client-server & security:**
      - Never trust client animation state for damage, economy, or progression. Use markers or animation completion as a *hint*, then validate on the server (distance, timing windows, stamina, etc.).
      - Replicate only what is necessary. Full pose data for many players can be expensive.
      - Ensure animation assets are owned by the player or experience so client-played player-character animations replicate correctly.
      
      **Performance notes:**
      - Preload everything.
      - Limit the number of simultaneously playing high-fidelity tracks + complex particle systems + transparent UI.
      - Use the lowest sufficient priority and weight.
      - Stop tracks promptly when they are no longer visible or relevant.
      
      ## Practical checklist for a new animated feature
      
      - [ ] Rig has proper Animator.
      - [ ] Animation authored or chosen from catalog with correct priority.
      - [ ] Markers added for all gameplay/VFX/UI sync points (with stable names).
      - [ ] Preload step in loading sequence.
      - [ ] Playback location decided (server for authority, client for cosmetics) and validated where necessary.
      - [ ] IK or constraints added if procedural posing is required.
      - [ ] Connected marker signals do the minimal work (spawn effect, play sound, start a short tween) and clean up after themselves.
      - [ ] Tested with multiple characters and on lower-end devices for frame pacing.
      - [ ] Track cleanup on death/remove or when the action is cancelled (disconnect marker/Stopped/Ended connections).
      
      
      
      ## Fixed simulation and animation callbacks
      
      `RunService:BindToAnimation()` runs at a fixed frequency. With `Workspace.UseFixedSimulation` enabled, it runs before Animator updates; otherwise it runs immediately before `BindToSimulation` callbacks, so do not assume pre-animation ordering. The returned connection can be disconnected for cleanup.
      
      Server-authority rollback can replay simulation callbacks and property-change signals. Keep synchronized simulation state separate from one-shot presentation or network side effects; `RunService:IsResimulating()` identifies replay steps where duplicate effects should be suppressed. Unsynchronized property access is restricted inside simulation callbacks.
      
      Source: https://create.roblox.com/docs/reference/engine/classes/RunService.
      
    • ui-tweens-and-sequences.md 7.3 KB
      ---
      read_when: "Tween UI properties, chain transitions, or reveal text"
      last_reviewed: 2026-06-17
      ---
      
      # UI tweens and animation sequences
      
      **Primary source:** https://create.roblox.com/docs/ui/animation
      
      ## TweenService for GuiObjects
      
      ```lua
      local TweenService = game:GetService("TweenService")
      local Players = game:GetService("Players")
      
      local playerGui = Players.LocalPlayer:WaitForChild("PlayerGui")
      local guiObject = playerGui:WaitForChild("ScreenGui"):WaitForChild("SomeButton")  -- or Frame, ImageLabel, etc.
      
      -- Best practice: work in scale + set a sensible AnchorPoint
      guiObject.AnchorPoint = Vector2.new(0.5, 0.5)
      
      local tweenInfo = TweenInfo.new(
          0.35,                           -- duration seconds
          Enum.EasingStyle.Quad,          -- or Sine, Cubic, Back, Bounce, Elastic, Exponential...
          Enum.EasingDirection.Out,       -- In, Out, InOut
          0,                              -- repeat count ( -1 = infinite )
          false,                          -- reverses
          0                               -- delay
      )
      
      local tween = TweenService:Create(guiObject, tweenInfo, {
          Size = UDim2.fromScale(1.15, 1.15),
          -- Position = UDim2.fromScale(0.5, 0.5),
          -- Rotation = 15,
          -- BackgroundTransparency = 0.2,
          -- ImageColor3 = Color3.fromRGB(255, 220, 100),
      })
      tween:Play()
      ```
      
      ## Recommended properties to Tween on common UI objects
      
      **Frame / CanvasGroup:**
      - Position, Size, Rotation, BackgroundTransparency, BackgroundColor3
      - CanvasGroup.GroupTransparency and GroupColor3 (affects all descendants as a batch)
      
      **TextLabel / TextButton:**
      - The above + TextTransparency, TextColor3
      - Avoid TextStrokeTransparency/TextStrokeColor3 for new work; add a UIStroke child and tween its Thickness/Color/Transparency for modern borders.
      
      **ImageLabel / ImageButton:**
      - The Frame properties + ImageTransparency, ImageColor3, ImageRectOffset/ImageRectSize (for sprite sheet tricks)
      
      **UIStroke (modern borders on almost anything):**
      - Color, Thickness, Transparency
      
      **Other useful:**
      - ScrollingFrame.CanvasPosition (smooth programmatic scrolling)
      - ViewportFrame + its world contents (you can tween camera CFrame or properties of 3D objects inside the viewport for "3D UI" effects)
      
      **Always add UIAspectRatioConstraint** when tweening Size on anything that has a designed aspect ratio. This prevents squashing on different screen sizes.
      
      ## Easing guidance
      
      - **Quad / Cubic**: general-purpose easing for UI.
      - **Sine**: gentler.
      - **Back**: slight overshoot then settle (great for "pop" on appear or button press).
      - **Bounce**: playful, use sparingly.
      - **Elastic**: rubber-band feel, can feel over-the-top.
      - **Constant** is an interpolation mode in the Animation Editor / curve animations, not a `TweenService` easing style. To snap a value instantly with TweenService, use a 0-duration tween or set the property directly.
      - Linear only when you truly want constant speed (rare for UI polish).
      
      Experiment in Studio. The visual graphs in the docs are accurate.
      
      ## Sequences, chaining, and state machines
      
      Simple chain:
      ```lua
      local grow = TweenService:Create(obj, info, {Size = UDim2.fromScale(1.2, 1.2)})
      local shrink = TweenService:Create(obj, info, {Size = UDim2.fromScale(1, 1)})
      
      local conn
      grow:Play()
      conn = grow.Completed:Connect(function(playbackState)
          if playbackState == Enum.PlaybackState.Completed then
              conn:Disconnect()
              shrink:Play()
          end
      end)
      
      obj.AncestryChanged:Connect(function(_, parent)
          if not parent then
              if conn then conn:Disconnect() end
              grow:Destroy()
              shrink:Destroy()
          end
      end)
      ```
      
      For more complex UI flows (open panel → show content → highlight button), maintain a small table of tweens or use a simple state enum + a "playNext" function. Cancel any in-flight tween before starting a conflicting one, and disconnect Completed connections when the sequence finishes or the GUI is destroyed.
      
      ## Typewriter / animated text reveal
      
      The official guide provides a complete reusable `AnimateUI` module using:
      - `LocalizationService` translator (optional)
      - `utf8.codes`/`utf8.codepoint` to iterate Unicode codepoints (use a grapheme-splitting library if you must animate by user-perceived character clusters)
      - Stripping RichText tags for the animation pass, then restoring or handling separately
      - `TextLabel.MaxVisibleGraphemes = index`
      - Small `task.wait(delayBetweenChars)`
      
      Call it from a LocalScript attached to the target TextLabel.
      
      ## Group transitions with CanvasGroup
      
      Instead of individually tweening 8 elements inside a panel when you want to fade the whole thing:
      1. Wrap them (or the important visual children) in a CanvasGroup.
      2. Tween only `GroupTransparency` (0 → 1) and/or `GroupColor3`.
      3. The group blends everything underneath with proper alpha.
      
      This is dramatically cheaper than tweening many individual transparencies and colors.
      
      ## 3D-in-UI via ViewportFrame + tweens
      
      ViewportFrame lets you embed a miniature 3D scene (with its own ambient lighting, models, and cameras) inside a 2D UI rectangle.
      
      Common pattern:
      - Tween the ViewportFrame's size/position/transparency for entrance.
      - Inside the viewport, tween the CurrentCamera CFrame, or properties on 3D parts/attachments (or even play AnimationTracks on a rig inside the viewport).
      - This is how many inventory inspectors, character previews, and "3D button" effects are achieved.
      
      **Important:** Real `ParticleEmitter`, `Beam`, `Trail`, and `Light` objects do **not** render inside `ViewportFrame`. Use the viewport's built-in `Ambient`, `LightColor`, and `LightDirection` for lighting.
      
      Performance warning: ViewportFrames have a cost. Limit how many are active and visible, especially on lower-end devices.
      
      ## Gotchas specific to UI tweens
      
      - ClipsDescendants does not clip rotated descendants reliably.
      - Tweening very large numbers of transparent UI elements at once is a major source of fill-rate / overdraw problems on mobile.
      - Always work in scale (0–1) + AnchorPoint for resolution independence. Hard pixel offsets are a maintenance nightmare.
      - UDim2.fromScale vs UDim2.new: prefer the former for clarity when doing relative work.
      - RichText tags will break simple character-by-character reveals unless you strip them first (as shown in the official typewriter example).
      - Tween objects are GC'd when no longer referenced and finished. Keep a reference only while you need to Cancel/Pause/Resume or listen to Completed.
      - Disconnect `Completed` connections and call `:Destroy()` on tweens when the GUI object is removed to avoid leaking memory.
      - Style transitions (beta) via the Style Editor are an alternative declarative approach. Good for consistent design-system motion.
      
      ## Multi-property tweens
      
      You can (and should) change several properties in one tween for cohesive motion:
      ```lua
      TweenService:Create(panel, info, {
          Size = UDim2.fromScale(0.9, 0.9),
          GroupTransparency = 0,          -- if inside CanvasGroup
          Position = UDim2.fromScale(0.5, 0.5)
      }):Play()
      ```
      
      ## When to prefer AnimationTracks over tweens in UI contexts
      
      Rare, but possible: if you have a complex repeating or blended motion that is easier to author once in the Animation Editor and then drive a ViewportFrame rig, or if you want marker events from "UI animation" data.
      
      In 99% of pure 2D GUI cases, TweenService (or the newer style transitions) is the correct, lighter-weight tool.
      
      See the official ui/animation.md page for the complete typewriter module and many more single-property code snippets.
      
  • scripts
    • AnimationLoader.lua 2.7 KB · in bundle
    • IKSetup.lua 1.6 KB · in bundle
    • TweenHelper.lua 2.2 KB · in bundle
  • SKILL.md 6.6 KB
    ---
    name: roblox-animation
    description: "Build or debug Roblox character animations, IK poses, animation-marker events, and UI or object tweens. Use for locomotion, emotes, motion blending, and timed effects."
    last_reviewed: 2026-06-17
    ---
    
    # roblox-animation
    
    Choose animation tracks for authored rig motion, TweenService for property changes, and IKControl for procedural poses. Validate gameplay outcomes on the server even when a client animation triggers the visual effect.
    
    **Key official sources:**
    - https://create.roblox.com/docs/animation (overview)
    - https://create.roblox.com/docs/animation/editor
    - https://create.roblox.com/docs/animation/inverse-kinematics
    - https://create.roblox.com/docs/animation/events
    - https://create.roblox.com/docs/ui/animation (UI tweens + typewriter)
    - Engine: Animator, AnimationTrack, Animation, AnimationClipProvider, IKControl, TweenService, TweenInfo, Tween, Enum.AnimationPriority, Enum.EasingStyle, etc.
    - Full reference: https://create.roblox.com/docs/reference/engine
    
    Cross-skill usage:
    - Combine with roblox-user-interfaces for UI motion details and "particles in UI".
    - Combine with roblox-vfx when animations should trigger emitters, beams, or trails via markers.
    - Combine with roblox-core for Animator acquisition, RunService timing, and preloading via ContentProvider.
    - Use roblox-networking to decide where to play/ control animations (server replication vs client-only cosmetics).
    
    ## Choose a motion system
    
    **3D rig/character motion that needs to look authored and blendable?**  
    → Animation system (Animator + AnimationTrack). Pre-authored in Editor or from catalog, played with priority/weight/fade/speed. Drive gameplay from markers.
    
    **Simple property changes, UI transitions, or one-off object motion?**  
    → TweenService. Use for GuiObjects (scale + AnchorPoint + UDim2), CFrame, Color3, Transparency, NumberSequence, etc.
    
    **Need procedural interaction with environment (hand reaching, head tracking, foot placement on uneven ground)?**  
    → IKControl (procedural) + optional AnimationTracks or constraints for limits. Often combined with animation events.
    
    **Combining systems:** Play a locomotion track on low priority while using IKControl or tweens for upper-body or UI overlays. Use markers in the track to start/stop IK or fire tweens/effects.
    
    See references/3d-animations.md and references/ui-tweens-and-sequences.md for details.
    
    ## Rig animations and IK
    
    Read [3d-animations.md](references/3d-animations.md) when authoring, loading, or blending rig animations, or configuring IK.
    
    - Load tracks through `Animator`. Choose priority, weight, fade time, and speed for the action.
    - Use named markers for footsteps, effects, and other timed events. Keep names stable when republishing assets.
    - Decide where playback runs and check asset ownership. Validate gameplay effects on the server.
    - Preload Animation assets and reuse loaded tracks. Stop tracks and disconnect their signals when the rig is removed.
    - For IK, define the chain root, end effector, and target. Tune responsiveness and joint limits in Play mode.
    
    ## UI animation with TweenService
    
    Read [ui-tweens-and-sequences.md](references/ui-tweens-and-sequences.md) for property examples, easing, chained transitions, and typewriter text.
    
    Use scale and AnchorPoint for responsive motion, and add an aspect-ratio constraint when the design requires fixed proportions. Use CanvasGroup for whole-panel fades. Cancel conflicting tweens and disconnect completion handlers when a sequence ends or its GUI is destroyed.
    
    For text reveal, use `TextLabel.MaxVisibleGraphemes` and account for localization and Unicode character boundaries.
    
    ## Combine motion with other systems
    
    - **Animation markers → everything else**: Footstep marker → play sound + emit particle at foot Attachment. Attack marker → enable hitbox or IK reach + spawn muzzle flash. "AbilityStart" marker → start a Tween on a UI cooldown ring or BillboardGui.
    - **Priorities + weight for layering**: Idle (low) + Walk (medium) + Action (high, weight 1.0 with fade). Use AdjustWeight and AdjustSpeed at runtime.
    - **Client vs Server playback**: For a player's own character, animations played on the client replicate to the server via the Animator (subject to ownership/permissions); for NPCs and other characters, the server is the authority. Cosmetic or prediction-friendly animations can be client-only. Gameplay-affecting timing (damage windows, movement locks) should be validated server-side; do not treat client markers as authoritative proof of a hit.
    - **Preload + cache tracks**: Load once per rig type, reuse the AnimationTrack objects. Use `AnimationClipProvider` for async animation loading when you need previews or streaming behavior.
    - **UI + 3D harmony**: Tween a 3D part or Attachment while a BillboardGui or SurfaceGui on it also tweens (or uses ViewportFrame for embedded 3D previews with parts/meshes/cameras; note that ParticleEmitters/Beams/Trails/Lights do not render inside ViewportFrame).
    - **Testing**: Different devices have different frame rates and input latency. Test easing feels on mobile + desktop. Use MicroProfiler for heavy simultaneous tweens.
    
    ## Common mistakes
    
    - `Humanoid:LoadAnimation(anim)` (deprecated; use Animator).
    - Polling `track.TimePosition` every frame instead of markers.
    - Tweening raw pixel offsets instead of scale + AnchorPoint (breaks on resolution/aspect changes).
    - Playing high-priority actions without fade time (jarring).
    - Never preloading (first play hitch).
    - Using the same low AnimationPriority for everything (idles fighting actions).
    - Ignoring IK constraints (elbows/knees bending backwards, wrists at impossible angles).
    - Tweening dozens of individual UI elements instead of using CanvasGroup or layouts.
    
    ## Examples and verification
    
    Adapt [AnimationLoader.lua](scripts/AnimationLoader.lua), [TweenHelper.lua](scripts/TweenHelper.lua), or [IKSetup.lua](scripts/IKSetup.lua) when the helper fits the task.
    
    For a changed animation, verify that it plays at the intended priority, fires its markers, and cleans up when the rig is removed. For UI motion, check the target screen sizes and cancellation path. Use [integration-and-events.md](references/integration-and-events.md) when motion drives another system.
    
    <!-- catalog:references:start -->
    ## Reference index
    
    - [3d-animations.md](references/3d-animations.md): Author or load rig animations, blend tracks, or configure IK.
    - [integration-and-events.md](references/integration-and-events.md): Synchronize animation markers with gameplay, effects, audio, or UI.
    - [ui-tweens-and-sequences.md](references/ui-tweens-and-sequences.md): Tween UI properties, chain transitions, or reveal text.
    <!-- catalog:references:end -->
    

Comments (0)

Sign in to join the conversation.

No comments yet.

Reviews (0)

No reviews yet.

Related