同一 Unity 场景中的多个 AI 角色:Convai 如何判断玩家正在与谁对话(第一部分)
Multiple AI Characters in One Unity Scene: How Convai Decides Who the Player Is Talking To (Part 1)
将三个 AI 角色放入同一个 Unity 场景大约需要四分钟。而判断玩家正在对谁说话,才是需要设计判断力的部分。
这种不对称性正是多角色会话的全部故事所在。没有可切换的多角色模式,没有需要添加的组件,也没有需要填写的字段。把第二个 ConvaiCharacter放进一个已运行的场景中,给它分配自己的 Character ID,房间里就有了两个。第四个、第十个也是如此。
变化在于,场景现在必须回答一个单角色场景从未需要回答的问题。玩家对着一个有 Sophia、Ethan 和 Marcus 站在其中的房间说话。谁来回应?单个 AI NPC 永远不会迫使这个问题出现。
本文介绍 Convai 多角色系列的第一部分,面向 Unity:包括设置、三种目标定位模式,以及它们底层的那条分层规则——大多数团队从未读过,然后花一下午去跟它较劲。它同样适用于 游戏、 培训和 信息亭。
同时观看本文所遵循的教程:
Unity 中的多角色会话是什么?

多角色会话是一个 Unity 场景,其中两个或更多 ConvaiCharacter 组件同时处于激活状态,与 Convai 共享一个房间。玩家一次只与一个角色互动, Convai Unity SDK 会自动判断目标,无需额外添加 组件。
无需任何配置的原因值得说明,因为它解释了下游的行为。单角色场景和多角色场景走的是同一条连接路径。唯一的区别在于该路径运行时能找到多少活跃角色。房间承载已加载场景中所有活跃角色,因此场景一旦变为多角色,房间也随之变为多角色。
那个设计选择会带来一个你会在 Convai Manager 检查器中注意到的后果。其场景设置部分会从 检查器中检测场景里的每个角色,并为每个角色列出复选框,另有一个"包含所有人"按钮。该列表中的任何内容都不是手动连接的。它是场景当前已包含内容的实时视图。
设置过程包括哪些内容?
三个步骤,前两个是你已经会做的事情。
从一个可用的单角色场景开始:一个 Convai Manager、一个 Convai Room Manager、一个 Convai Player,以及一个在播放模式下会回应的角色,如果你希望效果看起来正确,就接好唇形同步。如果你的还没做到这一步,Unity 安装与设置教程涵盖了这部分内容,入门指南也是如此。
添加更多角色。放入更多角色 预制体,或复制你已有的 GameObject。每个角色都携带与第一个角色相同的 Convai 组件,无论它来自 Avatar Studio还是你自己的美术管线。多角色场景中不存在额外的组件。
从 Convai 控制台为每个角色分配独立的 Character ID,其 知识、 性格和 核心 AI 设置也在那里管理。这一步至关重要,下一节将解释原因。
然后打开 Convai Manager,确认每个角色都已勾选或点击 Include Everyone,然后滚动到 Who The Player Talks To。该部分会在场景中有多个角色时出现,因为只有一个角色时没有需要决定的事项。
该 快速入门沿相同路径操作,并在每一步检查检查器读数。当场景中有两个角色时,Characters in Scene 显示 2,Joining the Room 显示 All 2。
为什么每个角色都需要自己的 Character ID?

因为 SDK 按 Character ID 路由所有权、参与者和音频。持有相同 ID 的两个角色不会各自获得独立的路由。第二个会与第一个冲突,房间会通过先注册的那个来响应两者。
这件事之所以比听起来更重要,在于场景如何获得第二个角色。复制一个已有的角色是常规做法,而复制品会携带原角色的角色 ID。被复制的角色永远不会获得属于自己的 ID。
Convai 会两次检查冲突,这一点足够不寻常,值得留意。
第一个检查在你编辑时运行。选择一个与已加载场景中另一个角色共享其 ID 的角色,其检查器会在所有其他部分上方显示一个标题为"另一个角色拥有此角色 ID"的错误。该消息会列出所有共享该 ID 的其他角色,而非仅列出找到的第一个,并且无论多角色会话是否处于活动状态,该检查都会运行,因为重复的 ID 在任何场景中都是错误的。一个验证辅助工具会将同一冲突报告为错误,因此持续集成运行或编辑器脚本可以在无人打开检查器的情况下捕获该问题。
第二个检查在房间连接时执行。若房间的活跃角色中包含两个 ID 相同的角色,该房间将直接拒绝连接,异常信息中会指明这两个角色及其共享的 ID。这一拒绝机制覆盖了进入房间角色列表的两条路径:连接时提交的完整角色阵容,以及房间运行期间后续添加的单个角色。
拒绝连接是这里一个值得玩味的选择。另一种做法——连接一个房间,让其中一个角色正常工作,而另一个角色悄无声息地消失——正是那种会被发布到构建版本中、三周后被人当作语音 bug 上报的情况。
ID 字段也会按其自身规则进行验证。它必须是 36 个字符,格式为 GUID,且不能有前导或尾随空白。检查器消息会具体指出哪一项验证未通过,其中一条警告指出很容易误将角色名称复制进来。重复比较会忽略大小写和周围空白,因此仅大小写不同的两个 ID 被视为同一个 ID。
Convai 如何判断玩家正在与谁对话?

Convai Manager 的 Who The Player Talks To 下有一个名为 Chosen By 的字段,其中包含三种模式。该设置位于管理器上而非组件上,原因在于一条值得借鉴的设计原则:一个角色能正常工作的场景,在第二个角色被放入后必须继续正常工作。一条需要有人找到并添加目标组件后才生效的规则,本质上只是一个换了马甲的手动步骤。
Look At 是默认模式。它面向玩家视野中心最近的角色,以与视线方向的夹角为每个符合条件的角色打分,距离作为平局时的决胜条件。
Proximity 面向最近的角色,无论玩家恰好在看哪里。
Manual 只在游戏调用时切换目标,其他任何时间都不会切换。
哪种模式适合你的相机?
诚实的回答是,模式取决于相机,而非题材。
Look At 适用于第一人称和VR场景,以及任何摄像机方向即玩家视线的场景。在默认模式下,目标定位读取的是玩家的视线方向,而非向场景发射射线,这是一个有意义的区别。射线需要每个角色都有碰撞体,并且层掩码设置正确;如果缺少其中任何一项,或者有杂散碰撞体遮挡了射线,它就会静默失败。改为读取摄像机的前方方向,意味着鼠标、手柄、移动端触摸屏和头戴式显示器都以相同方式驱动目标定位,因为它们都不会改变摄像机的指向。无需碰撞体,无需层,无需输入接线。
Proximity 适用于俯视角和第三人称镜头,即镜头并非玩家视线的情况。否则,一个等距视角训练模拟或带有自由镜头的第三人称场景会将对话指向镜头恰好对准的任意角色,而非玩家身旁的角色。
Manual 适用于对话菜单、任务步骤和过场动画,在这些场景中,由游戏决定对话对象,而非由玩家的视角或位置决定。对于必须完整播放的叙事节拍,它也是正确的选择;当场景为脚本化时,它与叙事设计搭配使用,原因将在后文详述。
该视频使用了 Look At,它是大多数 3D 场景(包括 WebGL 构建)的默认选项,也是正确的起点。
另请观看: Convai Unity 安装与设置教程,如果您的场景尚未进行对话交互。
每个定向决策背后的三个层次
视频用三十秒一带而过,文档却花了数页篇幅来讲解的,正是这部分。 Convai Manager大约每秒重新执行定向规则十五次,而该规则共有三层。其中两层可以调节,第三层则不行。
知道你在哪个层级作战,能节省人们因瞄准而损失的大部分时间。
第一层:谁有资格
两个数值决定了一个角色是否有可能被称呼。
范围(Range),以 MaxDistance 暴露,默认值为 30 米。视角(Look Angle),以 MaxAngle 暴露,默认值为 35 度,从视线方向起测量,因此默认值描述的是玩家前方一个 70 度的锥形区域。扩大它,你就扩大了被视为称呼某人的 视野。
这些是描述空间形状的数值。当一个角色无论玩家多么用力地盯着看都无法被称呼时,一定是这两个数值之一将其排除在外。
第二层:切换的意愿程度
还有两个数值决定了一个有资格的挑战者需要满足什么条件才能接管对话。
Switch Margin 默认为 10 度,用于设定挑战者的得分必须比当前选择好多少,对话才会转移。它仅适用于 Look At,因为其度量单位是度。Switch Delay 默认为 0.2 秒,用于设定挑战者必须持续保持最佳选择多久,移动才会确认执行。在 Proximity 模式下,延迟是区分两个站在相同距离处的角色的依据,因为以度为单位的 margin 对以米为单位的规则毫无意义。
第二对参数是 迟滞,它的作用是防止闪烁。没有它,两个站得很近的角色会在不到一度的镜头移动中来回切换对话,而将视角扫过整个房间时,对话会交给每一个经过的角色。这两个缺陷在游戏中显而易见,在代码中却不可见,因此它们各自拥有独立的设置项。
每个字段都 钳制而非抛出异常。MaxAngle 接受 1 到 180 度,Switch Margin 接受 0 到 90,另外两个的最小值为零。超出范围的值会被拉回范围内,而不是导致场景崩溃。
第三层:无法关闭的规则
有三条规则支配目标选择,没有任何设置可以将其禁用,而每一条都是系统代你执行的礼貌性处理。
一瞥并非指向。在对话推进之前,某个角色必须成为更优选择片刻。扫过某人而未落定的目光不会改变任何指向。Switch Margin 和 Switch Delay 共同强制执行这一机制,但该原则在任何数值下均成立。
玩家自己的那句话就锁定了目标。对话不能在玩家说话说到一半时转移,因为一句话的后半句触及的角色与前半句不同,这不是事后修正能补救的。说话中途投出的一瞥会被记住而非丢弃,因此一个贯穿整句话的目光会在句子结束的瞬间转移对话,无需重复同样的注视。正是这个细节让轮流对话显得体贴而非迟滞。
目标永远不会自行清除。当没有符合条件的角色时,最后被对话的角色会保持对话状态,对话可用性会报告该角色是否尚能听到玩家。如果目标被清除,那就意味着玩家开口却无人应答,这看起来像是场景故障,而非只是没有特定对话对象。
第三条规则是最常被误认为 bug 的那条。玩家在转身后角色仍继续回应,这是系统在维持对话线,而非丢失了跟踪。
对话从哪里开始?
一个房间在玩家尚未注视或说任何话之前就打开了一个角色,因为对话总得从某处开始。
在 Convai Manager 检查器中指定一个初始角色,房间将始终从该角色开始,无论场景顺序或摄像机朝向如何。若未指定,房间将从场景顺序中的第一个角色开始。
该选择仅决定对话的起始位置。房间就绪后,目标规则会重新评估,对话将转向玩家所面向的角色,除非模式为手动。初始角色是一个起始位置,而非锁定。
在已连接的房间上通过 script 设置该值,会排队执行重连而非移动当前对话,这是你在场景中途调用前值得了解的区分。
如何为你自己的场景调整目标规则?
当角色无法被触及时,调整资格参数对;当对话切换过快或过慢时,调整切换参数对。三项调整可覆盖大多数场景。
当对话在两个相邻角色之间来回闪烁时,先提高 Switch Margin,若闪烁仍然存在,再提高 Switch Delay。
当注视某个角色时对话并未转向该角色,说明其距离或角度超出了 Range 或 Look Angle 的范围。放宽正在排除该角色的那一项。
当玩家扫视房间时目标切换过于频繁,提高 Switch Delay,使一瞥不再被计为一次对话指向。
较窄的 Look Angle 适合在数字孪生或展厅中相距较远的角色,因为它允许玩家在两者之间查看而不面向任何一方。较宽的 Look Angle 适合宽幅屏幕,此时位于画面边缘的角色仍然可见。调优指南涵盖了检查器字段和运行时等效项。
你能通过代码驱动对话目标吗?
可以,而且其接口范围比三种模式所暗示的要大。
TalkTo 将对话指向某个角色。随时调用都是安全的,当房间不是多角色房间或该角色不在其中时,调用不会产生任何效果。在玩家正在说话时调用,请求会被挂起,直到该句说完后再发送,这与脚本动作所遵循的礼貌规则相同。
SetInitialCharacter 选择房间连接时谁先说话,并受上述重连注意事项的约束。
对于希望自行掌控决策的团队,目标提供程序接口将直接取代内置模式。其 resolve 方法接收当前房间中所有角色(按稳定顺序排列)以及当前持有对话的角色,并返回下一个应持有对话的角色。返回空值或返回候选列表之外的角色,则对话保持原状。其中抛出的异常会被捕获并记录日志,而不会导致场景崩溃。
两个事件报告状态变化。一个在玩家输入结束后、SDK 尝试执行变更之前触发,此时变更仍可能失败。另一个在 Convai 的权威响应完成目标协调时触发,即一个往返之后。基于事件系统构建的项目则获得一个单一领域事件,携带阶段信息(requested、confirmed 或 failed),以及在失败时的拒绝原因。
还有一个可随时读取的判定结果,说明上一次决策为何如此:提案已持有对话、变更已提交、提案领先时间不够长、玩家正在句中,或上一次变更仍在进行中。最后这组原因正是调试目标定位与盲目猜测之间的区别。
如何在 Play 模式下验证设置?
在 Play 模式下选中 Convai Manager,然后打开其 Live 部分。它报告的内容比大多数团队预期的要多。
Characters in Room 读取房间开放时设定的角色数量。Talking To 显示当前被对话的角色名称,并随玩家转向而更新。Player Can Talk 在该角色能听到玩家时读取为 yes,并在角色刚进入房间后的短暂时间内报告该角色仍在加入中。Room Holds 在房间角色数超过一个时读取为若干角色。下方的 Room Roster 为每个角色列出一行,标记被对话的角色,并显示哪些角色已就绪。如果你希望在自定义 UI 中获取相同的状态,请将其与 transcript API配合使用。
Live 部分还会指出最后一次目标定位决策背后的判定结果,这正是有意保持目标与目标卡住之间的区别所在。
对于一次性报告,Convai 菜单下有一个故障排除工具,涵盖目标定位以及对话状态的其余部分。使用编码助手的团队可以通过诊断工具获取相同的报告,包括目标定位规则及其数值,以及这些数值是否仍为出厂默认值。面向 Unity 的 Convai MCP 工作流涵盖了该配置。
演示场景展示的内容

教程使用三个角色——Sophia、Ethan 和 Marcus——在一个小谜题中进行测试。凌晨两点,有人站在一栋空房子外面,街上的所有灯同时熄灭了。
玩家询问 Sophia 看到了什么。她描述了一个静止站在前门附近的身影。转向 Ethan,问他这是否奇怪,他说单看那个身影并不奇怪,但无法解释的是同时发生的停电。转向 Marcus,他看到了灯熄灭,并主动提到那栋房子已经空置三周了。
那段对话中没有任何内容是预设台词。让它奏效的是,每个角色都有自己独立的 Character ID,因此在 Convai 端拥有各自独立的知识库以及各自的背景故事、知识和性格。Ethan 先尝试给出常规解释,Marcus 则隐去那个让他不安的细节——这些都不是定向行为。它们是三个由不同素材构建的角色,被逐一回应。
定向层在发挥作用时是不可见的,这正是其要旨所在。口型同步以及玩家从未提及名称的每一个其他层也是如此。玩家转身,正确的角色便会回应。
常见问题及解决方案
注视某个角色不会切换对话。该角色的距离或角度超出了 Range 或 Look Angle 的范围。请放宽排除该角色的那个参数。
对话在两个角色之间闪烁。Switch Margin 或 Switch Delay 相对于他们站立的距离来说太低了。请先提高 margin。
完全没有切换发生。模式为 Manual,因此除了脚本调用外,没有任何东西会移动目标。要么通过代码驱动它,要么更改模式。
TalkTo 似乎没有执行任何操作,控制台记录了一条警告并指明了该角色。该角色不是当前房间的成员,控制台中指明了它。它从未被注册,或者自房间连接以来已离开房间。
对话似乎卡在了一个角色上。在假定存在故障之前,请先查看判定结果。被挂起的目标和被卡住的目标从外部看起来完全相同,需要通过原因代码加以区分。
房间拒绝连接,并指出了两个角色。它们共享同一个角色 ID。请在仪表板中为每个角色分配各自独立的 ID。
对于超出上述范围的问题,目标定位故障排除页面和多角色故障排除页面逐一介绍各种症状,而Convai 开发者论坛是提出设置问题的地方,此外还有指南与教程分类以及关于同一场景中的多个角色和VR 中的多个角色的现有帖子。本教程的讨论帖汇集了正在按相同步骤操作的人提出的问题。
第二部分包含什么内容?
第一部分是在共享房间内进行一对一互动。玩家与一个角色对话,该角色回应,其他角色则等待。
第二部分将这一机制扩展到全对全 感知,即玩家和角色都能保持对周围正在发生的对话和事件的感知,这样当附近有人说了与自身相关的内容时,角色就能做出反应。这与定向是不同的问题:定向决定谁来回答,而感知决定谁在听。
还有一条值得了解的 Playground 路径。在这一切进入 3D 项目之前,多角色对话可以先以聊天形式进行原型验证,支持添加多个角色、控制谁来回应,以及可在浏览器中测试的群聊对话。教程将其提及为一个即将推出的独立教程。
多角色会话真正发挥作用的地方
大多数值得构建的场景中都有不止一个角色。一个拥有多个承担不同角色的 NPC 的游戏。一个培训模拟,其中一名教官、一名助理和一名引导员在同一层楼工作。一个在不同站点设有工作人员的虚拟导览。一个社交空间、一个XR 环境、一个使用透视视觉的混合现实构建,其中角色与玩家共享同一个物理房间,一个拥有不止一位主持人的品牌体验。
在所有这些场景中,每个角色都带来自己的知识、自己的长期记忆、自己的行动、自己对场景的视野,以及自己出现在那里的理由。多角色会话所增加的是一个路由层,让玩家无需菜单、快捷键或你自己编写的接近触发器就能在它们之间切换。
快速上手
安装 Convai SDK for Unity,可从 Unity Asset Store获取,或者让编码助手为你搭建场景,然后按照入门指南让一个角色开口说话,再创建你的其他角色,并将每个 Character ID 复制到各自的 ConvaiCharacter 组件中。多角色快速入门将场景从一个角色扩展到两个,而一个已发布的示例场景则展示了多个角色、目标指向和转录 UI 协同工作的效果。
另外观看: Convai YouTube 频道上的 Unity、Unreal Engine 和 XR 教程系列其余内容。
常见问题
Convai for Unity 中的多角色会话是什么?
多角色会话是一个 Unity 场景,其中两个或更多 ConvaiCharacter 组件同时处于激活状态,并与 Convai 共享一个房间。无需切换模式,无需添加组件,也无需填写任何字段。该房间包含已加载场景中所有处于激活状态的 Convai 角色,SDK 会决定玩家正在与哪一个角色对话。
如何向 Unity 场景中添加第二个 AI 角色?
将第二个角色预制体拖入场景,或复制现有角色的 GameObject,然后从 Convai 仪表板为其分配一个专属的 Character ID。打开 Convai Manager,确认两个角色在 Scene Setup 下均已勾选,或点击 Include Everyone,Who The Player Talks To 部分即会出现。
为什么每个 Convai 角色都需要自己的 Character ID?
SDK 通过 Character ID 来路由所有权、参与者和音频。两个角色共用同一个 ID 时会发生冲突,而不是各自获得自己的回答,房间会通过最先注册的那个角色来回应两者。编辑时检查器会警告冲突,如果两个活跃角色仍然共用一个 ID,房间将拒绝连接。
Convai for Unity 中的三种角色选择模式是什么?
Look At 面向玩家视野中心最近的角色,按角度评分,距离作为平局时的决胜因素。Proximity 面向最近的角色,无论玩家看向哪里。Manual 仅在游戏调用 TalkTo 时更改目标。Look At 是默认模式。
我应该使用 Look At 还是 Proximity 定位?
在第一人称和 VR 场景中,相机方向即玩家视线,应使用 Look At。在俯视和第三人称相机中,相机并非视线本身,使用 Look At 会指向相机恰好对准的角色,而非玩家附近的角色,因此应使用 Proximity。
Convai 如何判断玩家正在与哪个角色对话?
Convai Manager 每秒重新评估约十五次。Range 和 Look Angle 决定谁有资格被对话。Switch Margin 和 Switch Delay 决定一个有资格的挑战者需要满足什么条件才能接管对话。除此之外,一瞥不会改变对话方向,目标不会在玩家说话中途移动,目标也永远不会自行清除。
为什么对话会在两个角色之间闪烁?
Switch Margin 或 Switch Delay 相对于角色之间的距离来说设置得太低,因此微小的摄像机移动就足以触发切换。先提高 Switch Margin,如果闪烁仍然持续,再提高 Switch Delay。
能否让多个 Convai 角色同时说话?
不会。房间中同一时间只有一个角色在回答,移动对话会结束上一个角色的回合,即使它还在说话中途。如果某句台词必须完整听完,请将目标设定设为手动(Manual),按自己的节奏推进对话,或者在该角色说话时避免移动目标。
房间连接时,哪个角色先说话?
房间打开时,显示的是在 Convai Manager 检查器中指定的初始角色(Initial Character)。如果未指定,则显示场景顺序中的第一个角色。该选择仅决定对话从哪里开始,因为除非模式为手动(Manual),目标设定会在房间就绪的那一刻重新评估。
来源:Convai 智能 NPC 与动态剧情 · convai.com