关于 scenario-godot-animation
面向动画师和技术动画师的 Godot 4.7.2 动画技能。它结合代码化设置、运动测量和姿势联系表,明确验证导入、动画树、分层及 IK。
主要功能
- 01审计导入动画片段与重定向骨架
- 02测量运动循环的足部速度
- 03用代码构建并驱动动画树
- 04设置筛选层与 IK
- 05通过联系表检查固定时刻姿势
- 06验证过场时间线与摄像机行为
适用场景
- 01让移动速度匹配支撑脚运动
- 02将动画片段重定向到人形骨架
- 03添加上半身动作和脚部定位
- 04检查过场时间线与摄像机检查点
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ scenario-labs/ skills --skill scenario-godot-animation安装后在 Claude Code 中输入/scenario-godot-animation确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/critique.mdexpert-notes.mdgui-paths.mdprocedures.mdsources.mdscripts/gd_anim.pyscripts/agentkit/animation/anim_audit.gdanim_capture.gdanim_cutscene.gdanim_ik.gdanim_import.gdanim_motion.gdanim_rig.gdanim_setup.gdanim_tree.gdanim_tween.gdcutscene_director.gdfoot_placer.gdlocomotion_state.gdpose_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>);如果无法等待,请根据工具架构继续操作,并标明缺失项。
首先确认
询问一次,然后执行:
- 动作来源:Mixamo 或其他 FBX、Blender glTF、动作捕捉、在 Godot 中手动制作关键帧,或纯程序生成。
- 骨架:人形(适用 SkeletonProfileHumanoid)还是自定义;静止姿势是 T 姿还是 A 姿;是否有真实的 Root 骨骼。
- 移动模型:速度驱动(原地片段)还是根运动;如果设计固定了目标速度,也请确认。
- 所需图层:上半身动作、瞄准或注视、崎岖地面的脚部 IK、受击反应。
- 共用片段的角色及其身高范围。
- 过场动画:时长、摄像机数量、是否必须冻结游戏逻辑、正在使用的对话系统。
- 物理帧率、渲染器和目标硬件(用于评估 IK 和修改器的开销)。
带门禁的工作流
-
工具包和项目。
gd_anim.install_animkit(P);确认project.godot为 3D 启用了 Jolt,并使用需求说明指定的渲染器。门禁:工具包的作业返回ok。 -
导入。 为循环动画命名并添加循环提示(
Walk-loop),导入一次,然后在.import文件中设置选项(gd_anim.set_import_options,P3)并运行--import。启用animation/import_rest_as_RESET。门禁:gd_anim.audit没有标记;每个循环都能循环播放;RESET 存在。 -
重定向。 根据导入的骨骼名称构建 BoneMap(
anim_import.gd:make_bonemap,P4);导入时:会变成_。门禁:骨架为%GeneralSkeleton,骨骼已重命名,采样姿势与源姿势的偏差在 2 mm 以内。 -
共享。 将动画片段作为 Animation Library 导入,为每个身体分别指定 BoneMap,并使用
anim_setup.gd:share_library(P5)附加。门禁:未解析的轨道数为 0,轨道布局一致。 -
速度。 为每个循环、每个身体设置
foot_speed(P9)。门禁:控制器和 BlendSpace 的速度偏差在 2% 以内。 -
树。 用代码构建(
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)触发动作。 -
图层和 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)。 -
摄像机和过场动画。 使用带球体形状的 SpringArm3D(P12);使用一条 AnimationPlayer 时间线(P13)。门禁:调用顺序和时间、检查点处的摄像机位置、
animation_finished、分段播放。 -
查看。 姿势表: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/s | P9 |
| 脚部滑动容差 | 支撑脚速度低于 0.1 m/s;速度误差在 2% 以内 [已添加] | 基线 G5,P9 |
| 移动交叉淡化 | 0.1 至 0.2 s;着陆为 0.05 s;末尾以 0.15 s 从 Land 过渡到 Ground | P6 |
| 导入 FPS | 30(默认 animation/fps) | 导入器 |
motion_scale(Normalize Position Tracks 之后) | 源髋部高度(测试骨架为 0.97 m) | P4 |
| IK 脚部误差 | 要求低于 2 cm,实测低于 0.1 mm | P10 |
| FootPlacer 射线 | 动画脚部上方 0.5 m 至下方 1.0 m;髋部下降限幅为 0.35 m | P10 |
| 弹簧臂 | 半径为 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 s | P11;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中)。
参考资料
references/procedures.md(P1 到 P16,实时结果,尚未运行)、expert-notes.md(注明来源的说法)、critique.md(评分标准,G5 基线评分)、gui-paths.md(编辑器点击路径)、sources.md。scripts/gd_anim.py:Python 辅助工具(安装、运行、绑定、姿势表、审计、 GLB 编辑、.import编辑、骨骼采样)。scripts/agentkit/animation/:anim_rig、anim_audit、anim_capture、anim_import、anim_setup、anim_tree、anim_motion、anim_ik、anim_tween、anim_cutscene,以及foot_placer.gd、locomotion_state.gd、cutscene_director.gd、pose_persist.gd。- 测试:
tests/code/godot-animation/test_anim_live.py(A1 到 A9、W)和test_anim_offline.py。