构建你的第一个多角色会话
在一个 Unity 场景中放入两个或更多 Convai 角色,将它们连接为一个共享房间,并确认房间已准备好接收输入。
构建一个场景,其中两个 Convai 角色共享同一个房间,从脚本中连接它,并确认两个成员关系都出现在名册中。本页假设你已经有一个可正常工作的单角色场景,并希望在其中添加第二个角色。
添加第二个 ConvaiCharacter 会改变整个场景的连接方式。只有一个已注册角色时,SDK 会连接单角色房间;有两个或更多角色时,它会发送名册,且会话会获得一个成员层。现有按角色 ID 解析消息的代码需要进行 角色标识与寻址.
先决条件
一个已经包含
ConvaiManager,ConvaiRoomManager,以及ConvaiPlayer的 Unity 场景。参见 构建自定义场景 如果你是从空场景开始。已配置的 API 密钥。参见 配置 API 密钥.
来自你的 Convai 控制台的两个角色 ID。
设置场景
连接并等待房间
ConnectAsync 会以 ConvaiOperationException 失败,当名册被拒绝或连接失败时,它的 Code 属性会携带会话错误代码。 WaitUntilReadyAsync 会以 InvalidOperationException 失败,当初始角色启动失败时,会携带消息 Initial character failed to start (<code>).。这两种错误都要处理——在 async void 方法中的未处理故障会被 Unity 悄悄吞掉。
using System;
using System.Threading;
using Convai.Runtime.Components;
using Convai.Runtime.Core.Async;
using Convai.Runtime.Room;
using UnityEngine;
public class MultiCharacterSessionBootstrap : MonoBehaviour
{
[SerializeField] private ConvaiCharacter _initialCharacter;
private readonly CancellationTokenSource _lifetime = new();
private async void Start()
{
ConvaiManager manager = ConvaiManager.ActiveManager;
if (manager == null || _initialCharacter == null)
{
Debug.LogError("[MultiCharacter] 请分配一个初始角色,并向场景中添加一个 ConvaiManager。");
return;
}
manager.SetExplicitConversationTarget(_initialCharacter);
try
{
await manager.ConnectAsync(_lifetime.Token);
}
catch (ConvaiOperationException error)
{
Debug.LogError($"[MultiCharacter] 连接失败({error.Code}):{error.Message}");
return;
}
catch (OperationCanceledException)
{
return;
}
if (!manager.TryGetRoomConnectionService(out IConvaiRoomConnectionService roomService))
return;
MultiCharacterRoomSession session = roomService.CurrentMultiCharacterSession;
if (session == null)
{
Debug.LogWarning("[MultiCharacter] 已作为单角色房间连接。请检查两个角色是否都已注册。");
return;
}
try
{
await session.WaitUntilReadyAsync(_lifetime.Token);
}
catch (InvalidOperationException error)
{
Debug.LogError($"[MultiCharacter] {error.Message}");
return;
}
catch (OperationCanceledException)
{
return;
}
foreach (CharacterRoomMembership membership in session.Characters)
Debug.Log(
$"[MultiCharacter] {membership.CharacterId} 成员关系 {membership.MembershipId} " +
$"状态为 {membership.Status}(初始:{membership.IsInitial})");
}
private void OnDestroy()
{
_lifetime.Cancel();
_lifetime.Dispose();
}
}验证房间
在基于该房间继续构建任何内容之前,请先在控制台中确认以下四点。
CurrentMultiCharacterSession不为null,脚本会通过不记录单角色警告来体现这一点。session.Characters为场景中的每个ConvaiCharacter持有一条成员关系。恰好有一条成员关系会记录
初始:True,而且它就是你分配的那个角色。每条成员关系都有一个不同的
MembershipId.
现在对房间说话会发送到初始角色。将输入路由到其他任何成员关系都是单独的一步;在你更改交互目标之前,房间会一直保持在初始角色上。
故障排除
控制台报告一行,以 [ConvaiRoomManager] 房间所有权未能解析出一个有效的对话目标。
场景拥有两个或更多角色,但没有将其中一个命名为目标。
调用 SetExplicitConversationTarget ,再连接,就像上面的脚本所做的那样。
连接失败,并显示 无法连接,因为没有可用的活动角色。
在 ConnectAsync 运行时没有解析出活动角色——例如,所有已拥有的角色都处于非活动或已禁用状态。
至少激活一个 ConvaiCharacter 在场景中,或者先调用 SetExplicitConversationTarget 并使用一个活动角色,再进行连接。
连接失败,并显示 多角色房间中的每个角色都需要一个角色 ID。
一个处于活动且启用状态的 ConvaiCharacter 有一个空的 角色 ID。一个没有 ID 的非活动角色不会触发此问题——它根本不会进入名册验证。
设置 角色 ID 字段,给场景中的每个活动角色都设置好,并且对任何非活动角色也要设置好,以便之后将其激活并通过 AddCharacterAsync.
连接失败,并显示 多角色名册包含空引用或重复的角色引用。
同一个 ConvaiCharacter 组件被注册了两次。
每个组件只注册一次。使用第二个组件实例来添加同一角色的克隆。
连接失败,并显示 多角色房间最多支持 50 个角色。
向管理器注册的活动且启用的角色超过 50 个。
在连接之前,将活动角色数量减少到 50 个或更少。
一个角色缺失于 session.Characters ,尽管它在场景中
那个角色的 GameObject 或 ConvaiCharacter 组件在房间连接时处于非活动或已禁用状态。SDK 会在启动名册中排除非活动角色,而不会报错。
在连接之前激活该角色,或者在连接后通过 在运行时添加和移除角色.
脚本记录了单角色警告
管理器连接时,只有一个角色处于活动且启用状态——通常是因为第二个 ConvaiCharacter (或其 GameObject)处于非活动状态。
请确认两个 GameObject 实例在执行连接调用之前都已在场景中处于活动状态。
后续步骤
角色身份与称呼名册就绪与部分调度多角色会话的工作方式最后更新于
这有帮助吗?