mcpField
S
scenario-godot-animation

scenario-godot-animation

github.com/scenario-labs创意与媒体1.2k165 次安装1 天前更新
代码仓库

关于 scenario-godot-animation

面向动画师和技术动画师的 Godot 4.7.2 动画技能。它结合代码化设置、运动测量和姿势联系表,明确验证导入、动画树、分层及 IK。

主要功能

  1. 01审计导入动画片段与重定向骨架
  2. 02测量运动循环的足部速度
  3. 03用代码构建并驱动动画树
  4. 04设置筛选层与 IK
  5. 05通过联系表检查固定时刻姿势
  6. 06验证过场时间线与摄像机行为

适用场景

  1. 01让移动速度匹配支撑脚运动
  2. 02将动画片段重定向到人形骨架
  3. 03添加上半身动作和脚部定位
  4. 04检查过场时间线与摄像机检查点

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/scenario-labs/skills --skill scenario-godot-animation

安装后在 Claude Code 中输入/scenario-godot-animation确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
critique.md
expert-notes.md
gui-paths.md
procedures.md
sources.md
scripts/
gd_anim.py
scripts/agentkit/animation/
anim_audit.gd
anim_capture.gd
anim_cutscene.gd
anim_ik.gd
anim_import.gd
anim_motion.gd
anim_rig.gd
anim_setup.gd
anim_tree.gd
anim_tween.gd
cutscene_director.gd
foot_placer.gd
locomotion_state.gd
pose_persist.gd

详细介绍

Godot 动画(动画师和技术动画师)

目标:Godot 4.7.2.stable、macOS、Forward+ 搭配 Jolt Physics。references/procedures.md 中的每个流程都已于 2026-10-02 在 4.7.2 中针对程序生成的人形角色进行实测,因此无需下载任何内容。

原则

  • 测量动作,不要凭目测。 行走只有一个正确的地面速度:让支撑脚停止滑动时的速度。从片段中测量该速度(anim_motion.gd:foot_speed),并将其用于 BlendSpace 点和控制器。对于重定向后的角色,速度会按 Skeleton3D.motion_scale 缩放(体型放大 1.15 倍的角色,在 1.2 m/s 的片段上以 1.38 m/s 行走)。
  • 代码负责决策,动画层负责呈现。 游戏逻辑负责速度和状态;AnimationTree 只通过 advance 表达式或参数读取这些值。即使移除动画树,控制器也必须继续工作(Fair Fight,jzuvd0Lstuw 00:05:46)。
  • 查看精确时刻。 跳转或逐帧移动到固定时刻,并打开接触表(gd_anim.pose_sheet)。实时截图落在的帧是随机的。
  • 图层必须说明自己控制哪些骨骼。 部分片段并不会始终保持部分动画:glTF 导出会为每个片段补齐所有已动画的关节,而默认确定性混合下未过滤的 OneShot 会将所有未列出的骨骼重置为 RESET。定义图层的是过滤器,而不是缺失的轨道。
  • 根据动作选择驱动方式。 使用原地片段的速度驱动式移动可保持操控响应;根运动适合需要双脚保持着地的一次性动作(闪避、攀爬、翻越)[新增]。常规移动动画集适合使用动画树;动作集非常庞大或程序化图层很多时,更适合使用代码加 SkeletonModifier3D 图层(专家们对此看法不一:Fair Fight 反对动画树,xpoPfUKI9tw;RiftOfNostaria、Bitlytic 和 Chris 则支持动画树)。对于运行时起始值未知的值,使用 Tween;对于已制作的多属性曲线,使用 AnimationPlayer(Queble,KUyQzjpRsU8 00:01:48)。
  • 静默失败在这里很常见。 BoneMap 引用不存在的骨骼、advance 模式设为 Enabled 时的表达式过渡、缺少 RESET 关键帧:这些情况在 4.7.2 中都没有报错。每次导入和每次修改动画树后都要检查。如果此处提到的同级技能不在可用技能中,请让用户安装(npx skills add scenario-labs/skills --skill <name>);如果无法等待,请根据工具架构继续操作,并标明缺失项。

首先确认

询问一次,然后执行:

  1. 动作来源:Mixamo 或其他 FBX、Blender glTF、动作捕捉、在 Godot 中手动制作关键帧,或纯程序生成。
  2. 骨架:人形(适用 SkeletonProfileHumanoid)还是自定义;静止姿势是 T 姿还是 A 姿;是否有真实的 Root 骨骼。
  3. 移动模型:速度驱动(原地片段)还是根运动;如果设计固定了目标速度,也请确认。
  4. 所需图层:上半身动作、瞄准或注视、崎岖地面的脚部 IK、受击反应。
  5. 共用片段的角色及其身高范围。
  6. 过场动画:时长、摄像机数量、是否必须冻结游戏逻辑、正在使用的对话系统。
  7. 物理帧率、渲染器和目标硬件(用于评估 IK 和修改器的开销)。

带门禁的工作流

  1. 工具包和项目。 gd_anim.install_animkit(P);确认 project.godot 为 3D 启用了 Jolt,并使用需求说明指定的渲染器。门禁:工具包的作业返回 ok。

  2. 导入。 为循环动画命名并添加循环提示(Walk-loop),导入一次,然后在 .import 文件中设置选项(gd_anim.set_import_options,P3)并运行 --import。启用 animation/import_rest_as_RESET。门禁:gd_anim.audit 没有标记;每个循环都能循环播放;RESET 存在。

  3. 重定向。 根据导入的骨骼名称构建 BoneMap(anim_import.gd:make_bonemap,P4);导入时 : 会变成 _。门禁:骨架为 %GeneralSkeleton,骨骼已重命名,采样姿势与源姿势的偏差在 2 mm 以内。

  4. 共享。 将动画片段作为 Animation Library 导入,为每个身体分别指定 BoneMap,并使用 anim_setup.gd:share_library(P5)附加。门禁:未解析的轨道数为 0,轨道布局一致。

  5. 速度。 为每个循环、每个身体设置 foot_speed(P9)。门禁:控制器和 BlendSpace 的速度偏差在 2% 以内。

  6. 树。 用代码构建(anim_tree.gd,P6):BlendTree 根节点、其中包含 StateMachine、带同步的 BlendSpace1D、带过滤器的 OneShot、TimeScale。门禁:使用脚本化输入运行 drive 时,得到预期的状态列表和时间;树审计通过。通过 drive 测试的过渡辅助函数:

    static func transition(expr: String, at_end: bool, xfade: float) -> AnimationNodeStateMachineTransition:
        var t := AnimationNodeStateMachineTransition.new()
        t.xfade_time = xfade
        t.advance_mode = AnimationNodeStateMachineTransition.ADVANCE_MODE_AUTO   # default Enabled never auto-fires
        if at_end:
            t.switch_mode = AnimationNodeStateMachineTransition.SWITCH_MODE_AT_END
        if expr != "":
            t.advance_expression = expr        # read on tree.advance_expression_base_node
        return t
    # sm.add_transition(&"Ground", &"Fall", transition("not on_floor and not jump_pressed", false, 0.2))
    

    在游戏逻辑中通过 tree.set("parameters/sm/Ground/blend_position", speed) 和状态节点的属性驱动它;通过 tree.set("parameters/act/request", AnimationNodeOneShot.ONE_SHOT_REQUEST_FIRE) 触发动作。

  7. 图层和 IK。 OneShot 过滤器(P7)、FootPlacer 加 TwoBoneIK3D(P10)。门禁:在 skeleton_updated 中读取,脚在踏步、坑洞和 15 度斜坡上与目标的距离均在 2 cm 以内。修饰器按子节点顺序运行,因此应先运行放置器(目标和髋部),再运行求解器:

    var ik := TwoBoneIK3D.new()
    skeleton.add_child(ik)                       # after FootPlacer
    ik.setting_count = 2
    for i in 2:
        var side: String = ["Left", "Right"][i]   # := cannot infer from an array index
        ik.set_root_bone_name(i, side + "UpperLeg")
        ik.set_middle_bone_name(i, side + "LowerLeg")
        ik.set_end_bone_name(i, side + "Foot")
        ik.set_target_node(i, ik.get_path_to(targets[i]))
        ik.set_pole_node(i, ik.get_path_to(knee_poles[i]))      # 0.6 m in front of the knee
        ik.set_pole_direction(i, SkeletonModifier3D.SECONDARY_DIRECTION_PLUS_Z)
    skeleton.skeleton_updated.connect(_check_feet)   # final pose, after every modifier and influence
    

    跑步时降低 influence,腾空时将其设为 0,以显示制作好的动作(Lukky,MbaPDWfbNLo 00:09:30)。

  8. 摄像机和过场动画。 使用带球体形状的 SpringArm3D(P12);使用一条 AnimationPlayer 时间线(P13)。门禁:调用顺序和时间、检查点处的摄像机位置、animation_finished、分段播放。

  9. 查看。 姿势表:T 姿势正面和侧面、8 个行走阶段、每种状态、IK 地形、过场动画时间线(P14)。门禁:每张表都已打开并说明。

专家检查清单(在计划中说明这些事项)

  • 每帧都会回滚修改器的输出(Fair Fight XFZQNsFejwk 00:02:04;P10 会在一帧后读取动画姿势)。这适用于后期效果;当修改器负责控制姿势时,先将 pose_persist.gd 的角色设为 RESTORE,最后设为 SNAPSHOT:这样,一个增量为 5 度的修改器会在 12 帧内达到 60 度,而不是停留在 5 度(P16)。RESTORE 会覆盖动画,因此绝不要在正在播放的片段上使用它。
  • IK 只解算位置。 TwoBoneIK3D 会让脚在 15 度斜坡上偏离 12.1 度;在其后添加一个 CopyTransformModifier3D(仅旋转,参考类型为 Node,并使用一个倾斜角度与地面一致的对齐节点),可在不移动脚的情况下将偏差降至 0.0 度(P16;Lukky MbaPDWfbNLo 00:07:49)。
  • 确定性 IK 每帧都从头开始解算;单次迭代的链需要将角度限制设为完整的 180 度(Lukky 00:04:46)。IterateIK3D 的 deterministic 默认值为 false;为迈步的腿启用它(MeroDev 17xi4vDqQJk 00:02:28)。
  • Bezier 曲线和属性轨道无法混合(文档):动画树会混合值、位置、旋转和缩放轨道。
  • Call Method 轨道不会在编辑器预览中运行(文档):请在运行时测试(P13)。
  • 捕获更新模式会将当前值与第一个关键帧混合:属性值为 5、0.5 秒处的关键帧值为 10 时,使用 play_with_capture 会在 0.25 秒处得到 7.5(P16)。
  • 缓存 find_track:当脚本要采样许多轨道时,将路径映射到索引的映射表缓存起来。Fair Fight 在大型绑定中测得性能提升 1.5 至 3 倍(XFZQNsFejwk 00:04:03 至 00:06:45);在 GDScript 的 22 轨道测试绑定中,性能提升为 1.2 倍(P16)。这要求所有片段使用相同的轨道布局,因此请关闭 animation/remove_immutable_tracks。
  • 用门控控制单次动画:同时使用 animation_finished 和一个标记,否则下一帧的移动调用会替换受击片段(DevWorm GMyw3eHDw7s 00:22:58)。实测结果:“hurt”播放了 0.4 秒,之后恢复行走(P16)。
  • Blender 源文件。 导出前将 Rigify Limb Segments 设为 1,并使用 Game Friendly 单根骨骼(CoderNunk 0wMONEpEXpQ 00:00:19、00:01:23)。nodes/apply_root_scale(默认值为 true)会将导入缩放烘焙到网格和片段中,根节点保持为 1(文档)。
  • BlendSpace2D 用于四向精灵:将点设在正负 1 处,轴范围设为正负 1.1,使对角线吸附到左侧和右侧;2D 中向上为负 Y(Chris WrMORzl3g1U 00:09:20、00:13:09)。

数值

项目数值来源
人类行走、跑步的地面速度行走约为 1.2 至 1.5 m/s,慢跑为 3 至 4 m/s [已添加]改为测量片段(P9)
无滑步速度实测在按 1.2 和 3.5 制作的片段上,行走为 1.200,跑步为 3.504 m/sP9
脚部滑动容差支撑脚速度低于 0.1 m/s;速度误差在 2% 以内 [已添加]基线 G5,P9
移动交叉淡化0.1 至 0.2 s;着陆为 0.05 s;末尾以 0.15 s 从 Land 过渡到 GroundP6
导入 FPS30(默认 animation/fps)导入器
motion_scale(Normalize Position Tracks 之后)源髋部高度(测试骨架为 0.97 m)P4
IK 脚部误差要求低于 2 cm,实测低于 0.1 mmP10
FootPlacer 射线动画脚部上方 0.5 m 至下方 1.0 m;髋部下降限幅为 0.35 mP10
弹簧臂半径为 0.2 的球体会在距离墙壁 0.2 m 加余量 0.01 m 处停止P12
IterateIK3D 默认值max_iterations 4,min_distance 0.001,angular_delta_limit 2 deg,deterministic false类参考
Tween 错开时间每项 0.05 s,每个 tween 0.2 sP11;aagPe4dvM2M 00:04:04
修改器开销Fair Fight 通过增量全局变换,将 2 ms 的叠加开销减半XFZQNsFejwk 00:14:07

质量门槛

使用 references/critique.md 评分;将每项实时检查记录为“在 Godot 4.7.2 中于 运行:通过,关键数值”,并将未运行的项目标记为“尚未运行”,同时注明原因。 阻断条件:每条轨道都能解析;循环能够循环播放,且 RESET 涵盖每条动画路径;速度符合实测的无滑步速度;树通过脚本驱动测试;已打开姿势表。另外:.import 编辑中不得包含 overwrite_axis 或其他 4.7.2 中缺失的键;新代码中不得使用 SkeletonIK3D;IK 结果只能在 skeleton_updated 或 modification_processed 中读取,绝不能从 _process 中读取。

常见错误

  • BoneMap 使用 mixamorig: 名称。 Godot 导入的是 mixamorig_Hips;骨骼映射找不到任何匹配项,骨架仍会被重命名为 GeneralSkeleton,所有动画库轨道都无法解析,而且不会打印任何内容。请根据导入后的名称构建映射;审计会标记缺少 Hips 的 GeneralSkeleton。

  • 表达式过渡仍处于 Enabled 推进模式。 它们永远不会触发。对每个由表达式或条件驱动的过渡设置 ADVANCE_MODE_AUTO(2)。

  • 同一帧内有两个自动过渡条件为真。 清除 on_floor 的跳跃会从 Ground 跳到 Fall,跳过 JumpUp。请为表达式添加保护条件(not on_floor and not jump_pressed),或将跳跃过渡的优先级设为 0。

  • 未筛选的 OneShot 或 Add 节点使用不完整动画片段。 确定性模式(AnimationTree 的默认模式):未列出的骨骼会回到 RESET,角色变成 T 字姿势。非确定性模式:它们会冻结。请筛选节点。

  • 没有 RESET。 导入的文件默认不包含 RESET;混合和已保存场景随后会从静止姿势或零值开始。使用 animation/import_rest_as_RESET,或在上游创建 RESET(Blargis,ghYilg9cq-I 00:02:39)。

  • 在 _process 中读取 IK 结果。 你会得到动画姿势。请在 Skeleton3D.skeleton_updated 中读取(影响计算完成后的最终结果),或在修饰器的 modification_processed 中读取(100 percent,影响计算之前)。

  • 在 Hips 上使用根运动。 它会晃动;请插入真正的 Root(FinePointCGI,fq0hR2tIsRk 00:04:35)。速度为 basis * get_root_motion_position() / delta。

  • 在重定向后的角色上使用固定速度常量。 更高的角色通过 motion_scale 会有更长的步幅;请针对每个角色重新测量。

  • Tween 没有终止保护。 同一属性上的两个 Tween 每帧都会同时写入(Queble,KUyQzjpRsU8 00:02:54)。请保留引用并调用 kill()。

  • 在无头模式或跳过的过场动画中使用方法轨道。 默认的 Deferred 调用会等待一帧;永不让出执行权的循环会在最后一次性触发所有调用。请使用 Immediate,或让出若干帧。

  • 在运行时编辑树节点。 它们由场景的所有实例共享;每个角色的值应放在 parameters/... 中。

  • 仅使用射线的弹簧臂。 摄像机会停在墙面上;请为弹簧臂添加球体形状。

  • 摄像机关键帧没有设置注视目标。 过场动画摄像机的旋转关键帧发生漂移,导致最后 5 s 没有拍到主角;请在时间轴表上检查构图,而不是只检查第一个和最后一个关键帧。

  • 在已有自身动画片段的角色上加载动画库。 在第二个角色的 AnimationPlayer 上跳过导入,这样只会播放共享动画库(Quilled,nb6uSeEZFCI 00:04:36)。

交接

  • scenario-godot-expert: 运行协议、gd_run、捕获和审查工具。请先阅读。
  • scenario-godot-gameplay: CharacterBody3D 控制器和树读取的状态;使用方法轨道设置命中箱。
  • scenario-godot-3d-world: FootPlacer 和弹簧臂的碰撞层;IK 测试几何体。
  • scenario-godot-pipeline-automation: 批量导入和大规模编辑 .import 文件,以及 CI 运行。
  • scenario-godot-ui、scenario-godot-vfx、scenario-godot-audio: 超越 Tween 的菜单动画;从动画片段和过场动画中添加关键帧的效果与音效。
  • scenario-godot-performance-export: 在目标硬件上测量修饰器和树的开销。
  • blender- 技能:* 在源端设置 Root 骨骼、Rigify Game Friendly 导出、NLA 下推和循环提示。

Godot 4.7 说明

  • 从 4.6 起,SkeletonModifier3D 中提供 IK 系列:TwoBoneIK3D、FABRIK3D、CCDIK3D、JacobianIK3D、 SplineIK3D;设置按索引指定(set_root_bone_name(i, ...)、set_target_node(i, path)、 set_pole_node、set_pole_direction)。SkeletonIK3D 已弃用。
  • 自定义修改器应重写 _process_modification_with_delta(delta);_process_modification() 已弃用。不要自行应用 influence。
  • retarget/rest_fixer/retarget_method(0 None、1 Overwrite Axis 默认值、2 Use Retarget Modifier) 取代任何 overwrite_axis 键;RetargetModifier3D 可用于运行时重定向(此处未运行)。
  • tween_await(signal).set_timeout(s) 是 4.7 新增功能;tween_subtween 从 4.4 起提供。
  • 动画标记和 play_section_with_markers(4.3+);4.7 中的 Animation.length 为 double; 动画名称为 StringName。
  • AnimationMixer 是 AnimationPlayer 和 AnimationTree 的基类:root_motion_track、 deterministic(在播放器中为 false,在树中为 true)、callback_mode_process、 callback_mode_method。
  • 在 4.7.2(P6)中观察到:priority(数值越低优先级越高)也会决定同一帧内多个自动过渡均为 true 时采用哪个过渡,而不只是决定 travel() 路径;在首次调用 advance() 前调用 travel(),会让状态机以该状态启动且不会报错;过渡的 advance_mode 默认值为 Enabled(仅 travel)。
  • 观察结果(P10):modification_processed 报告的是应用 influence 之前的修改器结果;skeleton_updated 提供混合后的最终姿势;在这两个信号之外读取骨骼姿势时,得到的是动画姿势。
  • 观察结果(P3):手动编辑的 .import 文件可通过直接运行 --import 应用;片段名称会去除循环提示后缀,但会保留 loop 前缀;片段名称中的 . 会变成 _。
  • Skeleton3D 不允许骨骼名称中包含 : 和 /;4.7.2 中对此错误的报错字符串格式不正确(记录在 tests/OPEN_ISSUES.md 中)。

参考资料

评论

支持 Markdown