身体动画工作原理
了解分层动画图如何播放待机、说话、移动、动作和指向动作,以及对话状态如何驱动它。
ConvaiBodyAnimationController 构建一个分层的 PlayableGraph 直接针对 Humanoid Animator ——没有 Animator Controller 资源,没有在 Animator 窗口中编写的状态,也没有过渡。本页说明这个图是什么样子、每一层由什么驱动,以及当不止一层同时想要控制手臂时,这些层如何进行解析。
层级堆栈
该图运行六层,从基础姿势一直到最具体的覆盖层。
运动(基础)
全身
待机变体池,以及用于起步、走跑混合、停止和转向的 NavMesh 同步状态机。
交谈
默认上半身,每个条目可用全身
DialogueState.Speaking,按实时语音能量缩放,并在回应接近结束时释放。
Action
每个条目可用全身、上半身或自定义掩码
PlayAction 呼叫和 Convai 动作。全身动作会暂停运动,并压低其上的覆盖层。
指向
上半身
PointAt,在达到顶点时保持,并在目标移动时重新瞄准。
移动交谈
手臂和手
一种叠加式或柔化覆盖式的边走边说覆盖层,因此交谈手势不会让手臂在迈步中途僵住。
交谈节拍
手臂和手,叠加
短促的语音起始和指示性手势重音。
每一层都会在给定的 tick 中报告它想要的权重;随后由单一仲裁器决定最终的端口权重,因此没有两层能在同一帧里向同一个端口写入冲突的权重。
内容和行为是两个独立的资源
一个 ConvaiBodyAnimationSet 提供这些片段:待机和交谈变体、运动片段、命名动作以及指向方向。一个 ConvaiBodyAnimationConfig 提供这些调校项:淡出时序、语音能量缩放,以及在 身体动画配置参考中涵盖的大约一百个行为字段。可直接在控制器上分配二者,或将它们一起打包到一个 ConvaiBodyAnimationProfile 中,用于跨角色的基于预设的路由。参见 构建动画集 了解如何为一个集合编写内容。
对话状态如何驱动交谈层
交谈层读取 对话状态 来决定播放哪个片段池,而不只是是否播放:
说话中
该集合的 Talk 池,按实时语音能量缩放。
倾听中 / 关注中
该集合的 Listen 池,如果集合作者定义了它的话。
思考中,在短暂的进入延迟后持续保持
该集合的 Think 池,如果集合作者定义了它的话。
被打断
当前交谈姿势会短暂冻结,然后比正常淡出更快地释放。
Listen 和 Think 是可选池。未定义它们的集合,包括 SDK 随附的默认集合,会在这些状态下回到待机,而不是播放某个姿势——角色不会因为缺少内容而冻结或摆出错误姿势。
说话层如何释放
交谈层不会等待 DialogueState 离开 说话中 才开始收回手势。当角色具有 Lip Sync 时,交谈层还会读取还剩多少语音要播放,以及结尾是否已知。一旦剩余时间降到或低于 Talk Release Lead 秒 (0.6 秒(默认),该层会提前开始正常释放——手势减速,并在回应最后几个词播放时逐渐减小权重,而不是一直以满权重继续直到 说话中 结束后再在动作中途冻结。
如果没有 Lip Sync 读数,交谈层只会在 DialogueState 离开 说话中。请参见 身体动画配置参考 用于 Talk Release Lead 秒 以及影响释放的其他字段—— Talk Release Delay Seconds 和 Talk Release Playback Speed.
层级仲裁
动作所有权优先于指向和交谈:正在运行的全身动作会压低所有其他覆盖层,因此二者不会争用同一组骨骼。指向和交谈可以同时播放——角色可以一边指向某个东西,一边继续用另一只手臂做手势。仲裁器每个 tick 都会根据各层报告的期望权重来解决,而不是根据层级中的顺序或组件添加的顺序。
运动是可选的
ConvaiNavMeshLocomotion 驱动第 0 层的行走和慢跑状态,但没有运动组件的角色依然是完整且有效的配置:待机、交谈、动作、手势和指向都可以原地工作。只有在角色需要移动时才添加运动——参见 配置运动.
下一步
身体动画快速上手构建动画集对话流程最后更新于
这有帮助吗?