For the complete documentation index, see llms.txt. This page is also available as Markdown.

配置移动

为 Convai 角色添加基于 NavMesh 的移动,调整其步行和慢跑速度,并为自定义移动器手动报告位移。

添加 ConvaiNavMeshLocomotion 添加到 Convai 角色,使其能够在烘焙的 NavMesh 上行走和慢跑,调整其速度和转向行为,并通过 IConvaiLocomotionSourceConvaiTravelIntent进行连接。角色上运行 Convai 身体动画且还需要移动时,请使用本页面。


前提条件

  • ConvaiBodyAnimationController 已添加到角色。对于身体动画而言,移动是可选的——没有移动组件的角色会原地待机、说话、做手势和指向。

  • 如果使用 ConvaiNavMeshLocomotion,则场景中需要有烘焙的 NavMesh。SDK 依赖于 com.unity.ai.navigation (2.0.0),因此 窗口 > AI > 导航 以及 NavMeshSurface 组件无需额外安装即可使用。


为角色添加 NavMesh 移动

1

为地面烘焙 NavMesh

打开 窗口 > AI > 导航,将可行走几何体标记为静态(或添加一个 NavMeshSurface 组件),然后进行烘焙。角色必须站在烘焙的网格上。

2

添加组件

选择角色并使用 添加组件 > Convai > Embodiment > NavMesh Locomotion。这会添加 ConvaiNavMeshLocomotion.

ConvaiNavMeshLocomotion 需要一个 NavMeshAgent。如果角色没有该组件, Awake 会使用默认设置添加一个。

3

验证代理位于网格上

进入播放模式并调用 MoveTo (参见 从脚本移动角色 如下),或者查看场景视图的 Gizmo;在选中对象时,它会绘制当前路径。


配置移动速度和转向

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 路径。仅限编辑器。

步行速度慢跑速度 会被 ConvaiBodyAnimationController在角色上存在控制器时测得的动画片段速度所覆盖。仅在没有身体动画控制器、独立使用 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 返回 trueIsMoving 变为 true.

角色在以下情况后滑行 Stop()

症状: 角色的脚停止移动,但身体仍会继续滑动片刻。

原因: Stop() 会在通知动画移动结束的同一帧清除路径并将速度归零,因此一个惯性滑行的代理(慢跑速度下约 0.8 米)可能会超过已经稳定的动画。

解决方法: 使用 StopGracefully() 来进行决定后的停止,而不是 Stop();将 Stop() 保留给真正的中断。

验证: 角色的稳定停步动画会在其实际停止的位置落脚。


下一步

播放动作和手势身体动画配置参考身体动画脚本参考

最后更新于

这有帮助吗?