Communitygithub.com

ridhotamma/roblox-animation

为R6和R15角色设计、预览并导出Roblox动画。将描述的动作(如拳击、踢腿、剑挥、闪避等战斗动作,足球射门、投篮或运球等体育动作,循环动作、表情、舞蹈、空翻及其他特技)转化为带有交互式查看器和故事板的3D预览动作,然后生成烘焙好的关键帧,输出为KeyframeSequence(.rbxmx文件)以及Studio命令行脚本。每当用户需要Roblox动画、关键帧、KeyframeSequence、Motor6D姿势、角色攻击/表情/待机/跑步循环,或要求修正/重定时现有动画时,即可使用此技能,即使他们只说“让我的Roblox角色做X动作”。

roblox-animation 是什么?

此技能用于在Roblox中为R6和R15角色创建高质量动画。它将用户描述的动作(如战斗、体育、循环动作、表情等)转换为一个JSON格式的动作规范,然后经过引擎处理,生成3D预览、故事板(PNG/SVG)、HTML交互式查看器,以及可直接导入Roblox Studio使用的烘焙关键帧(.rbxmx文件)和Lua脚本。工作流包括:确定动作参数、拆分为阶段、编写规范、构建、检查报告和故事板、迭代修正,最后交付预览和导出文件。引擎自动处理关节数学、插值、足部接地等复杂计算,确保动画流畅且可交互查看。支持使用标签、事件标记和道具(如球、剑)来丰富动画细节,导出文件包含单帧线性缓动,保证Studio中的播放与预览完全一致。

兼容平台~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/ridhotamma/roblox-developer-skills/tree/HEAD/skills/roblox-animation

在你喜欢的 AI 中提问

打开一个已预加载此 Agent Skill 的新对话。

文档

Roblox 动画(R6 / R15)

您将动作编写为一个小的 JSON 动作规范:一组用解剖学术语描述的关键姿势(如“右上臂向前90°”、“膝盖弯曲60°”)。集成的引擎会自动处理手动容易出错的部分:两种角色模型的Roblox关节数学、插值、保持脚部贴地、3D预览器、合理性警告以及烘焙关键帧导出。

用户通过观看来评判结果,因此循环为:规划阶段 → 编写规范 → 构建 → 自行查看故事板 → 修正 → 交付预览 + 关键帧。 不要跳过查看步骤;在纸面上看起来正确的姿势编号实际上往往是错误的(手臂穿过胸部,踢腿从未到达球)。

工作流程

  1. 确定动作。 角色模型(R6或R15;只有在确实无法推断时才询问,否则默认使用R15并说明),惯用手,循环或单次,大致时长,以及需要的游戏逻辑挂钩(打击帧、球释放、脚步声)。对于明确的要求,立即开始构建。
  2. 在编写数字之前将其拆分为阶段。 几乎每个动作都是:准备 → 预期 → 动作 → 跟随 → 恢复。阅读 references/motion-cookbook.md 中您要做的类型(战斗、体育、循环动作、特技、R6特有内容);其中有时间表和姿势食谱。
  3. 将规范写入 <name>.json。 从 examples/ 中最接近的文件开始,而不是从零开始。
  4. 构建: node <skill>/scripts/ranim.cjs <name>.json --out out(可以传递多个规范;它们在一个预览中显示为标签页)。只需要Node,无需安装包。
  5. 读取报告(打印在stdout上的内容)。它列出了每个关键帧头部、手和脚的实际位置(studs:R = 角色右侧,U = 地面以上,F = 前方)并打印 WARN 行。使用这些位置检查意图:拳头真的在胸部前方吗?脚在球的高度吗?
  6. 使用读取工具查看 out/storyboard-<Name>.png(每个关键帧从3/4视图和侧视图)。如果没有生成PNG,则使用无头浏览器截图 out/preview.html 或读取SVG。将每个面板与您计划的阶段进行比较。
  7. 修正并重新构建,直到姿势清晰可读,并且警告消失或已明确接受。通常需要两到三轮。
  8. 交付: 交互式 out/preview.html(作为工件发布或发送文件),加上 out/<Name>.rbxmx 和 out/<Name>.lua。如果可能,请内联显示故事板图片。简要告知用户如何将其导入Studio(见下文),以及存在哪些动画事件。

动作规范

{
  "name": "JabCross",            // 成为KeyframeSequence名称和文件名
  "title": "刺拳-交叉组合",      // 预览器中显示
  "rig": "R15",                  // "R15" 或 "R6"
  "priority": "Action",          // Idle | Movement | Action | Action2..4 | Core
  "loop": false,
  "description": "预览旁边显示的一两句话。",
  "keys": [
    { "t": 0, "label": "防御", "note": "在阶段列表中显示。",
      "pose": { "UpperTorso": { "turnR": 10, "bendFwd": 8 },
                "LeftUpperArm": { "fwd": 50, "out": 8 }, "LeftLowerArm": { "bend": 120 },
                "LeftFoot": "flat" } },
    { "t": 0.1, "label": "刺拳", "ease": "out", "copy": "防御",
      "pose": { "LeftUpperArm": { "fwd": 86, "in": 22 }, "LeftLowerArm": { "bend": 6 } } },
    { "t": 0.8, "label": "恢复", "copy": "防御" }
  ],
  "markers": [ { "t": 0.1, "name": "Hit", "value": "刺拳" } ],
  "props": [ { "type": "ball", "radius": 0.6, "color": "#e07a2c", "keys": [ ... ] } ]
}

(注释仅用于说明;文件必须是纯JSON。)

可选的顶层字段:fps(默认为30;非常快的动作使用60),duration(默认为最后一个关键帧的时间),grounding("off" 表示手动控制高度),mirror: true(左右翻转整个片段,例如左脚版本),endKeyframe: true。

关键帧

  • t 秒(对齐到帧)。第一个关键帧在0。
  • pose 将关节名称映射到通道(角度单位)。关键帧中未列出的关节仅通过该关键帧进行插值,因此中间关键帧可以只提及相关的关节。从未提及的关节保持静止状态,并且不会被导出;第一次在关键帧0之后出现的关节从静止状态(0°)开始。
  • copy:先前关键帧的标签或索引。姿势从副本开始,pose 覆盖其中的部分。"mirror": true 与 copy 配合使用时,会交换左右两侧,这是通过半步长制作步行/跑步循环的方法。
  • ease 控制 离开 此关键帧的段曲线:smooth(默认,自然缓动,无过冲),linear,in(开始慢,结束快:释放打击的蓄力),out(开始快,结束后稳定:冲击),inOut,hold,overshoot,anticipate,bounce,elastic。
  • lift:此关键帧时身体最低点离地高度(studs)。默认0。这是制作跳跃的方式;请参阅接地。

关节和通道

角度是解剖学意义上的,同一个词表示身体两侧的相同含义,因此镜像姿势不需要改变符号。每个通道都有一个相反方向的别名;使用阅读更自然的那个。

关节通道(相反方向的别名)
根:LowerTorso(R15),Torso(R6)bendFwd(bendBack),turnL(turnR),leanR(leanL),moveFwd(moveBack),moveR(moveL),moveUp(moveDown),单位studs
脊柱:UpperTorso,HeadbendFwd(bendBack),turnL(turnR),leanR(leanL)
上肢:Left/RightUpperArm,Left/RightUpperLeg;R6 Left Arm,Right Arm,Left Leg,Right Legfwd(back)身体前后摆动肢体,out(in)远离/靠近身体,twistOut(twistIn)沿其自身长度旋转
Left/RightLowerArm,Left/RightLowerLegbend:肘部和膝盖的自然弯曲方向(0 = 伸直)
Left/RightHand,Left/RightFootfwd(back),out(in),twistOut(twistIn)。脚部也接受字符串 "flat"

地标:手臂 fwd: 90 笔直向前,fwd: 180 笔直向上,out: 90 是T形姿势。腿 fwd: 90 是齐腰高的前踢。旋转是父子关系组合的,因此胸部的旋转会带动手臂;将 Head 向相反方向旋转以保持眼睛注视目标。

R6有六个部位,没有肘部、膝盖、手或脚,因此轮廓来自躯干和整个肢体角度;稍微夸张一些。R6肢体名称包含空格("Right Arm")。

接地

默认情况下,引擎每帧降低或提升根关节,使身体最低点恰好位于地面上方 lift studs处。后果:

  • 蹲下、弓步和劈叉会自动降低臀部;对于站立姿势,永远不要手动调整臀部高度。
  • R15脚部的 "flat" 会解析脚踝,使脚底平贴地面,无论腿部在做什么。对于每只着地的脚都使用它;对于空中的脚或踮起的脚,给出明确的角度("back": 40 = 脚趾尖)。
  • 跳跃是空中关键帧的 lift 值(起跳小,最高点最大,落地0)。空中的身体旋转作用于根关节:后空翻是根关节的 bendBack 在关键帧之间从0→360(角度是连续的,因此360是完整转体,而不是“回到0”)。
  • 接地开启时,根关节上的 moveUp 被忽略。仅在游泳或攀爬等与地板无关的情况下设置 "grounding": "off"。
  • 游戏内的跳跃和冲刺通常由角色控制器移动,而不是动画。对于在游戏跳跃期间播放的动画,摆出身体姿势并将 lift 保持在0。对于自包含的表情、带跳跃的攻击和空翻,使用 lift 和 moveFwd。如果片段结束时位置与开始不同,报告会发出警告,因为Roblox会在轨道停止时将身体弹回原位。

标记和道具

  • markers 成为 KeyframeMarkers,在游戏中通过 track:GetMarkerReachedSignal("Hit") 读取。在每个游戏逻辑关心的帧上放置一个:命中窗口、球接触或释放、脚步声、声音提示。
  • props 是 仅预览(不被导出),用于根据交互对象判断动作。type: "ball" 带 radius,或其他任何类型的盒子,带 size: [x, y, z](剑是细长盒子)。at 可以是部件名称(道具跟随该部件;offset: [right, up, fwd] 在部件自身轴中)或固定点 [right, up, fwd](从角色地面点起的studs)。使用多个 keys 时,道具在锚点之间移动;arc 为离开该关键帧的段添加抛物线上升(射门或传球)。请参阅 examples/jump_shot.json 和 examples/soccer_kick.json。

什么算做好的动画

  • 可读的轮廓。 在故事板中,每个关键帧应仅从其轮廓就可识别。如果两个相邻的关键帧看起来相似,则其中一个没有作用。
  • 时间上的对比。 慢节奏的预期,非常快的动作(2到4帧),短暂保持在跟随阶段,较慢的恢复。关键帧之间均匀间隔是最常见的导致动作感觉无重量的原因。
  • 整个身体都参与其中。 力量从脚和臀部开始,然后是胸部,肩膀,最后到手或脚。在蓄力时给臀部和胸部一个反向旋转,并让远处的手臂平衡近处的手臂。
  • 双脚保持不动。 着地的脚在报告中保持其R和F数值在关键帧之间不变。如果必须移动,请在其间的关键帧中抬起(一步)。
  • 零警告,或者为保留的每个警告给出理由。限制是自然的关节活动范围;超出限制通常意味着意图使用不同的通道。

将其导入Roblox Studio

向用户提供两种方法以及事件名称。

  • 命令栏(最快): 在资源管理器中选中角色模型,打开“视图”→“命令栏”,粘贴 <Name>.lua 的全部内容,按回车。KeyframeSequence会出现在角色模型的 AnimSaves 中(如果未选中任何对象,则在ServerStorage中),动画编辑器可以加载并对其进行微调。
  • 文件: 将 <Name>.rbxmx 拖入Studio视口,或右键单击服务→从文件插入。
  • 发布: 要在实时游戏中播放,必须上传:在动画编辑器中打开并发布,或右键单击KeyframeSequence→保存到Roblox,然后在 Animation 对象中使用生成的资产ID,并使用 Animator:LoadAnimation。对于在Studio中的快速本地测试,game:GetService("KeyframeSequenceProvider"):RegisterKeyframeSequence(seq) 返回一个临时ID。Studio的菜单会不时更改;如果某一步与用户看到的不匹配,请说明并查找当前措辞,而不是坚持原有说法。

导出是烘焙的:每帧一个关键帧,带有线性缓动,因此Studio在任何该类型的角色模型上都能精确播放预览显示的内容。仅导出规范中动画化的关节,因此仅上半身的动画会保持下半身自由,以便进行默认行走。R15输出带有 AuthoredHipHeight,因此可以重新定位到其他比例的角色。

文件

  • scripts/ranim.cjs — 引擎、预览器和导出器集成在一个文件中。也可以作为模块使用:const R = require('.../ranim.cjs'); const c = R.compile(spec); R.report(c); R.sample(c, t)。
  • scripts/selftest.cjs — 检查关节数学与Roblox的Motor6D公式。编辑引擎后运行它。
  • examples/ — soccer_kick,jump_shot(带球道具的体育),jab_cross(R15战斗),r6_sword_slash(R6带武器战斗),backflip(全身旋转和跳跃),r6_run(镜像循环)。
  • references/motion-cookbook.md — 按类型分的时间表和姿势食谱。编写前阅读相关章节。

相关技能