mcpField
S
scenario-unity-animation

scenario-unity-animation

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

关于 scenario-unity-animation

scenario-unity-animation 面向使用 Unity 的 Agent,指导其通过数据构建和验证动画系统,无需依赖 Animator、Timeline 或 Scene 窗口。内容涵盖导入、控制器、绑定、摄像机、根运动和过场,并以可测量的检查验证结果。

主要功能

  1. 01自动化动画导入规则
  2. 02Animator 控制器与混合树
  3. 03确定性动画采样
  4. 04绑定与摄像机设置
  5. 05Timeline 过场验证

适用场景

  1. 01导入并审查角色动画片段
  2. 02检查移动速度和脚部滑动
  3. 03构建瞄准绑定并验证约束
  4. 04测试摄像机混合与过场交接

安装

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

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

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

包含的文件

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

references/
critique.md
expert-notes.md
gui-paths.md
procedures.md
sources.md
scripts/
ut_animation.py
scripts/AgentKit/Animation/
AnimCinemachine.cs
AnimControllerBuilder.cs
AnimImport.cs
AnimPackages.cs
AnimPlayMode.cs
AnimProcedural.cs
AnimRigging.cs
AnimSampler.cs
AnimTimeline.cs
AnimUtil.cs
scripts/Runtime/
AgentAnimationGraph.cs
AgentLightClip.cs
AgentLightTrack.cs
AgentMarker.cs
AgentMarkerReceiver.cs
AgentRootMotionMover.cs
SecondOrderDynamics.cs

详细介绍

Unity 动画(Animator 和 Technical Animator)

在 Unity 中进行专业级动画工作,关键在于顺序和测量:由列表顺序决定哪个图层、约束、过渡或摄像机生效;则通过从动画片段中获取的数值来判断脚步、瞄准和混合是否正确。没有 Animator、Timeline 或 Scene 窗口的 Agent,会根据数据构建所有内容(AnimatorController、TimelineAsset、Cinemachine 和 Rigging 组件),以确定性方式逐步运行、测量并查看接触表。目标版本:Unity 6000.3.21f1、Cinemachine 3.1.7、Animation Rigging 1.4.1、Timeline 1.8.12。如果这里提到的同级技能不在可用技能中,请让用户安装该技能(npx skills add scenario-labs/skills --skill <name>);若无人在场,则根据工具架构继续操作,并标明这一缺口。

必备背景: scenario-unity-expert(通道、审查循环、6.3 中的陷阱)。工具包:scripts/ut_animation.py 和 scripts/AgentKit/Animation/ 中的 C# 作业(命名空间 AgentKit.Animation),以及 scripts/Runtime/ 中的运行时代码。使用 ut_animation.install(P) 安装。

立场(专业经验增量)

  1. 顺序决定行为,无处不在。 Animator 层级越低,优先级越高(iHeartGameDev,W0eRZGS6dhQ [00:05:04]);Additive 会在遇到第一个 Override 时停止 [00:09:46];默认情况下,过渡不可中断;启用 Ordered Interruption 后,只有排在当前运行过渡之前的过渡才能插入,顺序相同则按列表顺序处理(Catherine Proulx,Unity 博客;实测:她的 None、有序、无序和同帧情况均可复现)。中断时会从冻结的姿势快照开始混合(实测:中断帧骨骼运动速度为 0 度/秒):应让用于中断的过渡保持较短 [推论]。骨架约束按深度优先顺序求解,先脊柱,再头部或手部(Code Monkey,luBBz5oeR4Q [00:06:20];实测头部误差为 0.0 度,而非 17.9 度)。
  2. 混合树坐标使用游戏内单位。 子项使用实测的 averageSpeed / averageAngularSpeed,而不是 0 / 0.5 / 1(_J8RPIaO2Lc [00:16:30]);将运行时参数限制在子项的范围内,否则速度持续上升时,边缘姿势会保持不变 [帧 00:13:38]。脚本速度与动画片段不一致会导致脚底滑动(Ketra Games,mNxEetKzc04 [00:00:32];实测滑动速度 p50 为 0.19,而非 1.14 米/秒)。
  3. 当待机姿势与行走姿势不同时,待机应作为独立状态(IsMoving 上不设置退出时间),混合树从慢速行走开始(mNxEetKzc04 [00:08:54])。只有在脚本速度驱动原地动画片段时,才适合将待机放在混合树原点(_J8RPIaO2Lc [00:04:24])。
  4. 根运动按动画片段和轴分别决定(6.3 手册):待机动画烘焙旋转、Y 轴和 XZ 轴;直线移动动画烘焙旋转和 Y 轴;转向动画保留旋转;改变高度的动画不烘焙 Y 轴,并使用 Based Upon Feet,这样混合时不会漂浮,脚本控制的跳跃也不会重复叠加动画片段中的髋部上升。**Based Upon 从不会导致漂移:**烘焙的轴无论该设置为何值,位移都为零;它只决定姿势的位置。Original 保留文件中的朝向和位置(Ketra 以这种方式烘焙 Mixamo 待机动画,不会漂移);Body Orientation 会重新居中动作捕捉片段(实测 30 秒内:两者漂移均为 0 米,但 Original 的朝向偏差 88 度,位置偏移 2.43 米;XZ 未烘焙时漂移 0.246 米)。在 OnAnimatorMove 中只调用一次 CharacterController.Move(deltaPosition + y),绝不要使用 deltaPosition * Time.deltaTime [00:07:21]。Y 轴已烘焙的动画片段中,Animator.gravityWeight 为 1;Y 轴未烘焙的动画片段中为 0,并在过渡期间混合(手册;实测如此,关闭根运动时则始终为 0)。
  5. 从一个参考文件自动化导入,并限定作用文件夹(git-amend,V9_Z6hUOG_8):在 OnPreprocessModel 中设置骨架,在 OnPreprocessAnimation 中设置动画片段;规则变更时递增 GetVersion();绝不要在回调中重新导入。角色类型应根据文件名或规则确定,绝不要取动画片段名称:每个 Mixamo 动作名称都是“mixamo.com”。引用 FBX 子资源中的动画片段;在切换到 Humanoid 前复制的动画片段会保留骨骼路径(BEZHVYk6Fa4 [00:12:03];实测:它使 humanoid 移动了 0.0 度,而切换后复制的版本移动了 40.1 度)。从不同层级结构中 Copy From Other 会导入 0 个动画片段,且仅在导入日志中报告(已观察到)。默认关闭 Translation DoF [00:02:21]。
  6. 蒙皮掩码创建层,参考姿势创建 Additive 层。 没有蒙皮掩码的 Override 层会替换整个身体;Additive 动画片段只有在其创作时的基础姿势之上才有效(W0eRZGS6dhQ [00:05:33],[00:09:57])。导入时使用蒙皮掩码,去除动画片段不需要的手指和 IK 目标(手册,成本)。
  7. 摄像机:只用一个 Brain,移动目标,并根据游戏类型选择 Rig(Unity CM3.1 系列)。Smart Update 加 Late Update 在出现抖动时优先进行混合(Brain 文档)。肩后视角使用 Third Person Follow;FreeLook、Camera Offset 和 Deoccluder 会相互冲突(u0a1F6BlczE [00:02:41])。程序化 Position Control 会覆盖动画;绝不要将其设为移动物体的子级(XTVzs4B1d7I [00:03:10])。位于目标相对两侧的摄像机会穿过目标进行混合:使用 CylindricalPosition 提示(实测:不设置时为 0.5 米,朝向点积为 0.0;Cylindrical 时为 5.02 米,朝向点积为 0.995;仅设置 IgnoreTarget 时仍为 0.5 米)[00:13:32]。Deoccluder:将玩家设为 Ignore Tag,将玻璃设为 Transparent Layers;触发器永远不计入(实测)。Timeline 会覆盖 Brain:在其停止前,优先级设置会被忽略(Play 模式下实测)。
  8. Timeline:持续动作使用轨道,瞬时事件使用标记,没有负载时使用 Signals(Ciro Continisio,gsEe0_o_934 [00:18:53])。接收器会收到路由给它的每一条通知:应检查类型 [帧 00:22:57]。拖动时间轴时混合器也会运行;在 OnGraphStart 中生成对象,并在之后销毁 [00:45:30]。

首先确定

平台和帧预算(性能交接数据);3D 骨骼动画还是 2D 精灵(精灵请转至 scenario-unity-2d);绑定类型(用于重定向和 Mixamo 时选 Humanoid;只有一个骨架且注重 成本时选 Generic;Generic 根运动通过 Root Node 生效);根运动(玩家脚部质量)还是 原地动画(NavMesh AI、精确控制速度);内容来源:Mixamo(用于 Unity 的 FBX,30 fps,关键帧 简化为 none,使用同一个 Mixamo 角色,动画片段选 Without Skin;根运动:In Place 关闭, Character Arm Space 调高;mNxEetKzc04 [00:03:04]、_J8RPIaO2Lc [00:01:24])、要拆分的 动作捕捉录制、DCC;摄像机风格;项目中是否已有 CM2?;过场动画时长和分支。默认值: Humanoid、玩家使用根运动、CM 3.1.7、30 fps Timeline、Input System。

工作流

  1. 包。 使用 AnimPackages.Add 和 ["[email protected]", "[email protected]"](异步,quit=False), 然后执行 ua.install(P)。GATE:ua.pinned_packages(P) 全部通过。
  2. 导入。 ua.default_rules("Hero.fbx", files) -> AnimImport.ImportDrop(规则 JSON、 角色优先、蒙版、修复层级不匹配)。使用 AnimSampler.ClipProfile 拆分动作。GATE:审计 counts.error == 0,Avatar 有效且为 human,每个动画片段均为 human_motion,没有 anim.role_fallback,文件夹外的 FBX 仍为 Generic;AnimImport.AuditClips 没有 anim.generic_duplicate。
  3. 控制器。 Spec -> AnimControllerBuilder.Build(蒙版、层、auto 树位置、 带中断设置的过渡、哈希类)。GATE:counts.error == 0;位置与测得的速度一致; ua.blend_tree_checks(tree, param_ranges) 通过;在 SampleStates 中使用类似 ua.interruption_probe_spec 的事件证明紧急退出有效。
  4. 采样和外观。 AnimSampler.SampleStates(Rebind、固定 Animator.Update;events、 trace、每个样本的 clip/controller)、LocomotionMetrics(单独检查一个动画片段时用 clip)。GATE:状态符合预期;蒙版骨骼为 0.000 deg;地面速度在 5 % 以内;滑步 p50 < 0.25 m/s; idle 30 s 漂移 < 1 cm;未烘焙 Y 轴的动画片段(启用根运动)中 gravityWeight 为 0;已打开表格。
  5. 绑定。 先执行 AnimRigging.BuildAimRig,再执行 AuditRigs。GATE:头部 < 1 deg,手部 < 1 cm,没有 rig.solve_order,已查看帧;移动一个目标,绝不重新绑定(rig.runtime_rebind); 目标移至遮挡物后方时,绑定权重逐渐淡出(Htl7ysv10Qs [00:07:54],Play 模式下采样 Rig.weight)。
  6. 摄像机。 AnimCinemachine.SetupCameras(rigs、blend_hint、deoccluder)、AuditCameras、 CameraProbe(Manual Update;obstacles、遮挡 linecast、series)。GATE:每个事件都有实时摄像机; ua.camera_probe_checks 为空(无翻转、无穿越摆动、无被遮挡或位于几何体内部的帧); ua.jitter_metrics 反转 < 5 % [added];审计 0 warn。
  7. Timeline。 AnimTimeline.BuildCutscene、SampleCutscene(拖动、帧)、PlayCutscene (Play 模式:标记、信号、实时摄像机、交还控制权)、AuditTimeline。GATE:绑定正确; 混合数值正确;没有根节点跳变;标记和信号各触发一次;审计 0 warn;结束后 Brain 的优先级摄像机处于实时状态。
  8. 验证和代码。 AnimProcedural.RootMotionPlay(每帧一次 Move), ua.scan_csharp(Assets) 通过,将数据交给 scenario-unity-performance。

完整代码和记录结果见流程说明: references/procedures.md。

数值

数值相对于来源
Clamp(0.1 x length, 0.1 s, 0.5 x length)单次混合;在 length 减去 blend 处淡出fQzKJO-0dS8 [00:07:58]
0.7 aim / 0.3 look手部瞄准时的胸部权重 / 头部注视luBBz5oeR4Q [00:06:53]; Htl7ysv10Qs [00:08:59]
-100..100 deg头部瞄准限制,后方淡出权重Htl7ysv10Qs [00:06:58]
Min 1 s, Wait 0针对闪烁状态的 State-Driven 摄像机u0a1F6BlczE [00:09:32]
primary 2, fallback 1ClearShot 优先级u0a1F6BlczE [00:14:53]
30 fps, keyframe reduction noneMixamo 下载_J8RPIaO2Lc [00:01:24]
T < sqrt(4 k2 + k1^2) - k1二阶稳定性KPoeNZZ6H4s [00:12:29]
1.08 / 3.51 m/s, -98 / +77 deg/sUnity 示例动作捕捉中的行走、慢跑和转身观测
0 m vs 0.246 m30 s 静止漂移,XZ 已烘焙 vs 未烘焙观测
0.5 m vs 5.02 m摄像机最近距离,无提示 vs 圆柱形观测

质量门槛

  • **可测量:**导入审计和 AuditClips 无问题;控制器审计;遮罩检查;速度误差在 5 % 以内; 滑动 p50;静止漂移;绑定错误;摄像机探测检查和抖动;Timeline 绑定、事件、 审计;每帧一个 Move;C# 扫描。
  • **视觉:**每个阶段都要根据 references/critique.md 评审联系表(T 字姿势、脚陷入地面、手臂穿过 身体、突变、摄像机翻转、取景);ut_review 无标记。

常见错误

错误表现修正
采样时的 Culling Mode 不是 Always Animate批量捕获显示绑定姿势采样器会强制使用 Always Animate(已观察到)
根据 Take 名称选择标志每个 Mixamo 动画片段都使用相同的循环和烘焙标志根据文件名或规则指定角色;重命名动画片段
未限定范围的导入处理器项目中的每个 FBX 都变成 Humanoid使用规则文件或 assetPath 守卫;ua.scan_csharp
根 Y 已烘焙的跳跃动画片段混合时漂浮;髋部抬升叠加到脚本控制的跳跃上不烘焙 Y,Based Upon 设为 Feet
切换到 Humanoid 前复制 .anim动画片段无法在 humanoid 上播放切换后重新复制,或引用 FBX 动画片段
在不同层级结构上使用 Copy From OtherFBX 导入后没有动画片段,控制台也没有提示查看导入日志;每个文件使用自己的 Avatar(已观察到)
将漂移归咎于 Based Upon待机动画在循环播放时逐渐滑开烘焙 XZ;Based Upon 只负责放置姿势
参数超出树的范围速度升高,动画却没有变化将参数限制在子项范围内
头部约束位于胸部之上头部无法对准目标在兄弟节点顺序中将身体放在前面
摄像机位于相对两侧,且没有提示混合时摄像机穿过头部并翻转两侧都使用 CylindricalPosition
将玻璃或触发器视为墙壁摄像机跳到窗户前使用 Transparent Layers;忽略触发器
过场期间提高优先级直到过场结束才有变化由 Timeline 控制 Brain
在编辑器脚本中设置 PriorityBrain 仍使用旧摄像机使用 cam.Prioritize()(已观察到)
拖动时间轴来测试标记或交接标记不会触发;最后一个镜头仍在播放使用 PlayCutscene(已观察到)
OnNotify 未检查类型对每个标记都会做出响应使用 if (n is MyMarker m)
过早应用 Optimize Game Objects场景实例消失在较后阶段、发布前应用(BEZHVYk6Fa4 [00:07:22])

更多 Agent 陷阱(归档时 GUID 会变化、每个文件一个类、在 Unity 对象上使用 ??、读取播放模式数据):references/procedures.md。

交接

  • 接收: 来自 scenario-blender-export、scenario-maya-expert 或 scenario-3d 的角色 FBX 和动画片段;来自 scenario-unity-architecture 的输入操作;来自 scenario-unity-gameplay 的移动速度、NavMesh Agent 和游戏事件;来自 scenario-unity-pipeline-automation 的导入流水线约定。
  • 交付: 向 scenario-unity-gameplay 提供控制器、参数约定(Speed m/s、TurnRate deg/s、IsMoving、Jump)、哈希类、根运动控制器(垂直方向来源);向 scenario-unity-rendering-lighting 提供摄像机切换(Camera Cut 时重置时间效果)和 Timeline 灯光轨道;向 scenario-unity-performance 提供 Animator 数量、剔除模式、导入遮罩、延后应用的 Optimize Game Objects;向 scenario-unity-vfx 提供 Signals 和 Activation 轨道。交付包:项目、作业、 审计 JSON、表格、指标、Verified 和 Assumed 列表。

Unity 6.3 说明

  • 6000.3.21f1 清单列出 Cinemachine 2.10.7;直接调用 Client.Add 却解析到了 3.1.7(实测): 仍需固定版本。CM3 使用 Unity.Cinemachine、CinemachineCamera 和组件;CM2 升级时,先将类型改为 CinemachineVirtualCameraBase,再执行 Upgrade Entire Project(无法撤销)。在 6.6 中,CM3、Timeline 和 Animation Rigging 将成为核心组件。
  • Timeline 1.8:editorSettings.frameRate。6.3 新增 Animator.ResetControllerState。已弃用的 ModelImporter 成员会在 6.5 中变成错误。
  • 模板仅运行 Input System;进入 Play 模式会重新加载域(Play 模式作业会在运行期间将其关闭)。

参考资料

  • references/expert-notes.md:专家的原则和判断,附来源和时间戳。
  • references/procedures.md:每项作业的参数、背后的 Unity 调用、实时测试和结果。
  • references/critique.md:用于评估骨骼绑定、混合、脚部、摄像机和过场动画的评分标准。
  • references/gui-paths.md:完成相同工作的窗口和菜单。
  • references/sources.md:所有来源、凭据、URL、最佳时间戳和修订历史。

评论

支持 Markdown