配置移动
为 Convai 角色添加基于 NavMesh 的移动,调整其步行和慢跑速度,并为自定义移动器手动报告位移。
添加 ConvaiNavMeshLocomotion 添加到 Convai 角色,使其能够在烘焙的 NavMesh 上行走和慢跑,调整其速度和转向行为,并通过 IConvaiLocomotionSource 或 ConvaiTravelIntent进行连接。角色上运行 Convai 身体动画且还需要移动时,请使用本页面。
前提条件
ConvaiBodyAnimationController已添加到角色。对于身体动画而言,移动是可选的——没有移动组件的角色会原地待机、说话、做手势和指向。如果使用
ConvaiNavMeshLocomotion,则场景中需要有烘焙的 NavMesh。SDK 依赖于com.unity.ai.navigation(2.0.0),因此窗口 > AI > 导航以及NavMeshSurface组件无需额外安装即可使用。
为角色添加 NavMesh 移动
配置移动速度和转向
ConvaiNavMeshLocomotion 公开以下 Inspector 字段:
速度配置文件
LocomotionSpeedProfile
自动
步行, 慢跑, 自动
一次移动是步行、慢跑,还是按目的地选择步态。 自动 慢跑经过 自动慢跑距离,较近时步行。
自动慢跑距离
float
6 (米)
>= 0.5
自动 配置文件阈值:距离大于此值的目的地将以慢跑前往。
最小慢跑距离
float
4.5 (米)
>= 0
短于此距离的路段始终步行,即使使用 慢跑 配置文件也是如此——慢跑需要空间来加速、匀速和停稳。
加速度
float
4 (米/秒²)
>= 0.5
代理加速度。Unity 自身的默认值 8 看起来会像突然猛冲。
步行速度
float
1.2 (米/秒)
>= 0.1
指定的步行速度。
慢跑速度
float
2.6 (米/秒)
>= 0.1
指定的慢跑速度。
每秒旋转角度
float
360
>= 10
沿路径移动时的转向速率。原地转身本身由动画驱动,不使用此值。
绘制 Gizmo
bool
true
—
选中对象时,在场景视图中绘制当前 NavMesh 路径。仅限编辑器。
在运行时通过 SetSpeedProfile(LocomotionSpeedProfile)更改配置文件。更改会立即应用于当前移动,包括步行↔慢跑的步态切换,也会应用于之后的每次 MoveTo.
从脚本移动角色
MoveTo 会将目的地采样到 NavMesh 上,并返回 false 当其 2 米范围内没有可行走地面,或者代理不在烘焙的 NavMesh 上时。 IsMoving, Speed, RemainingDistance,以及 Destination 读取当前移动状态。
Stop() 和 StopGracefully() 以不同方式结束移动:
Stop()
步行被中断——有新指令到达、组件被禁用,或其他事物接管控制。
在当前所在位置立即停下。路径会在此帧清除,速度同时归零。
StopGracefully()
角色决定停止——等待某人跟上,或接近跟随距离。
继续沿当前路径走到前方的制动点,减速,并完成一个稳定停步。仅当完全无法结束移动时返回 false ,此时会通过以下方式直接取消移动: Stop().
StopGracefully() 仍会报告 MoveEnded(false) ——角色停下了,但没有到达被指派前往的位置。使用 Warp(Vector3) 传送代理,同时清除所有路径。
使用自定义移动来源
ConvaiBodyAnimationController 公开一个 Inspector 字段: 移动提供程序覆盖,序列化为 _locomotionProviderOverride。分配一个 MonoBehaviour 其实现了 IConvaiLocomotionSource ,以便从不同于以下系统的移动系统驱动动画同步: ConvaiNavMeshLocomotion ——例如 CharacterController、根运动、补间或第三方导航。
IConvaiLocomotionSource 是最低限度的约定—— IsMoving, PathPending, Speed, DesiredSpeed, RemainingDistance, SignedAngleToSteering, Destination,以及 MoveEnded 事件。同一组件上还会将另外三个接口识别为可选功能;缺少某个接口只会禁用需要它的功能:
IConvaiLocomotionCommands
MoveTo(Vector3) / Stop() ——允许 ConvaiBodyAnimationController 以及 Convai 自身的动作执行器通过你的提供程序发出移动指令。
IConvaiManagedLocomotion
与动画片段同步的开始、停止和转向(FreezeAgent, BeginManagedMotion, SetManagedSpeed, EndManagedMotion, SetAnimationStartGate, ReleaseAnimationStartGate, CompleteMoveFromAnimation, ConfigureSpeeds)。没有它,移动仍会同步到你的来源所报告的速度和方向,但混合方式更简单。
IConvaiAnchorAlignment
BeginRootAlignment() / EndRootAlignment(Vector3) ——用于以下操作的根节点写入权限: PlayActionAt的对齐插值。没有它, PlayActionAt 会降级为播放未对齐的动作。
ConvaiNavMeshLocomotion 实现了全部四个接口,因此无需配置覆盖字段即可工作。
在没有 ConvaiNavMeshLocomotion 的情况下报告移动行程
ConvaiTravelIntent 是角色层级的衔接点,用于表明角色正在前往某处,因此其他组件——例如 Convai Gaze 在行走时注视路径——可以在其移动期间采取不同的行为。 ConvaiNavMeshLocomotion 会自动为其创建并向其报告;由以下方式移动的角色: CharacterController、根运动、补间,或没有 Convai 组件的导航代码,仍可获得基本支持,因为 ConvaiTravelIntent 还会观察角色自身的 Transform 移动。
对于脚本移动器,每一帧调用 ReportTravel 持续报告移动——不再重复的报告会自行过期:
ReportTravel(Vector3 worldDirection, float speed01)
报告此帧的方向和归一化速度。不含剩余距离详情。
ReportTravel(Vector3 worldDirection, float speed01, float remainingDistance)
相同,但包含已知的剩余距离。
ReportTravelTo(Vector3 destination, float speed01)
便捷方法:报告朝向 目的地 的行程,并在一次调用中将其设置为主体。
ClearTravel()
立即结束已报告的行程,无需等待其过期。
SetSubject(Transform subject)
声明该行程是关于 主体 (被跟随的人)——这会让 Gaze 等其他组件定期投以一瞥。
SetSubject(Vector3 worldPosition)
声明该行程是关于一个固定地点。
ClearSubject()
忘记该行程原本是关于什么。角色会继续注视道路。
ConvaiTravelIntent 会在角色实际开始移动的瞬间自动创建——除非你希望更改其检测阈值或关闭自动检测,否则无需自行添加:
自动检测移动
bool
true
—
检测角色自身 Transform 上的移动,无需任何 Convai 移动组件或代码报告。
移动速度阈值
float
0.35 (米/秒)
>= 0.01
低于该速度时,移动会被视为停稳、抖动或原地转身。
移动持续秒数
float
0.25
>= 0
移动需要持续多久才会被视为一次行程。
报告超时秒数
float
0.5
>= 0.05
已报告的行程在未重复报告的情况下保持有效的时长。
参考行进速度
float
3.6 (米/秒)
>= 0.1
归一化报告速度时被视为“全力”的速度。仅在没有其他来源提供该值时使用。
故障排除
角色不移动
症状: MoveTo 返回 false,或者控制台记录了一条指明角色名称的警告。
原因: 代理未站在烘焙的 NavMesh 上,或者目的地 2 米范围内不存在可行走地面。
解决方法: 在地面上烘焙 NavMesh(窗口 > AI > 导航),并确认角色从其上开始。
验证: MoveTo 返回 true 和 IsMoving 变为 true.
角色在以下情况后滑行 Stop()
症状: 角色的脚停止移动,但身体仍会继续滑动片刻。
原因: Stop() 会在通知动画移动结束的同一帧清除路径并将速度归零,因此一个惯性滑行的代理(慢跑速度下约 0.8 米)可能会超过已经稳定的动画。
解决方法: 使用 StopGracefully() 来进行决定后的停止,而不是 Stop();将 Stop() 保留给真正的中断。
验证: 角色的稳定停步动画会在其实际停止的位置落脚。
下一步
播放动作和手势身体动画配置参考身体动画脚本参考最后更新于
这有帮助吗?