> For the complete documentation index, see [llms.txt](https://docs.convai.com/api-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.convai.com/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/scripting-reference/convaimanager-api.md).

# ConvaiManager API

`ConvaiManager` 是 Convai Unity SDK 的主要脚本入口点。它初始化运行时，管理房间连接，拥有这些 `事件`, `音频`，以及 `转录文本` 外观封装，并通过类型化访问器提供对底层服务的访问。所有脚本交互都从这里开始。

**访问权限：** `ConvaiManager.ActiveManager` （单例）

```csharp
var manager = ConvaiManager.ActiveManager;
if (manager == null)
{
    Debug.LogError("场景中未找到 ConvaiManager。请通过 Convai → Create Manager 添加它。");
    return;
}
```

{% hint style="warning" %}
`ActiveManager` 返回 `null` 如果没有 `ConvaiManager` 存在于场景中，或者它尚未完成引导。使用前务必先判空，尤其是在可能 `OnEnable` 在管理器初始化之前。
{% endhint %}

***

### 状态属性

| 属性               | 类型     | 说明                                  |
| ---------------- | ------ | ----------------------------------- |
| `IsBootstrapped` | `bool` | 静态。当运行时完成初始引导后为 True——此时可以安全访问外观封装。 |
| `IsInitialized`  | `bool` | 当引导完成且事件中心可用时为 True。                |
| `IsConnected`    | `bool` | 当房间会话处于 `已连接` 状态时为 True。            |

***

### 外观封装访问器

| 属性     | 类型                  | Reference                                                                                                                                                                                            |
| ------ | ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `事件`   | `ConvaiEvents`      | [会话事件](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/scripting-reference/session-events.md), [角色事件](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/scripting-reference/character-events.md) |
| `音频`   | `ConvaiAudio`       | [音频 API](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/scripting-reference/audio-api.md)                                                                                                        |
| `转录文本` | `ConvaiTranscripts` | [Transcript API](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/scripting-reference/transcript-api.md)                                                                                           |

***

### 所有权属性

| 属性                            | 类型                               | 说明                                |
| ----------------------------- | -------------------------------- | --------------------------------- |
| `Characters`                  | `IReadOnlyList<ConvaiCharacter>` | 全部 `ConvaiCharacter` 当前由此管理器拥有的实例 |
| `玩家`                          | `ConvaiPlayer`                   | 该 `ConvaiPlayer` 由此管理器拥有的实例       |
| `ActiveConversationCharacter` | `ConvaiCharacter`                | 当前设置为对话目标的角色；可能为 `null`           |
| `ConversationMode`            | `ConvaiManagerConversationMode`  | 此管理器配置的对话模式                       |
| `ActiveConversationInputMode` | `ConversationInputMode`          | 当前生效的运行时对话输入模式                    |
| `PushToTalkKey`               | `KeyCode`                        | 在模式为 `按键通话`                       |

#### `ConvaiManagerConversationMode` enum

| 值                     | 说明                                     |
| --------------------- | -------------------------------------- |
| `UseRoomDefaults` (0) | 使用中配置的对话输入模式 `TurnTakingOptions` 上的管理器 |
| `HandsFree` (1)       | 设置免提（本地音频）模式，覆盖房间默认值                   |
| `按键通话` (2)            | 设置按键通话模式，覆盖房间默认值                       |

***

### 房间操作

#### `ConnectAsync`

```csharp
// 简单连接 — 使用场景配置
IConvaiOperation<RoomSession> ConnectAsync(CancellationToken ct = default)

// 使用运行时覆盖进行连接
IConvaiOperation<RoomSession> ConnectAsync(RoomSessionConnectOptions options, CancellationToken ct = default)
```

返回一个 `RoomSession` 成功后。参见 [操作与流类型](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/scripting-reference/operation-and-stream-types.md) 是位于 [异步模式](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/scripting-reference/async-patterns.md) 了解消费模式。

**`RoomSessionConnectOptions` 字段**

将此传递给第二个重载，以在连接时覆盖运行时行为。

| 字段                          | 类型                                    | 说明                                                                                                                    |
| --------------------------- | ------------------------------------- | --------------------------------------------------------------------------------------------------------------------- |
| `TurnTaking`                | `TurnTakingOptions`                   | 覆盖此会话的轮流配置。参见 [轮流模式](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/core-concepts/turn-taking-modes.md) 获取完整字段参考。 |
| `EndUserId`                 | `string`                              | 为此会话覆盖最终用户 ID（由长期记忆使用）                                                                                                |
| `EndUserMetadata`           | `IReadOnlyDictionary<string, object>` | 最终用户的附加元数据                                                                                                            |
| `ActionConfigOverride`      | `ConvaiActionConfig`                  | 为此会话覆盖动作配置                                                                                                            |
| `ActionDefinitionsOverride` | `List<ConvaiActionDefinition>`        | 覆盖为此会话注册的动作定义                                                                                                         |

```csharp
var options = new RoomSessionConnectOptions
{
    EndUserId = currentUser.Id,
    EndUserMetadata = new Dictionary<string, object>
    {
        ["department"] = "工程",
        ["cohort"]     = "2025-Q2"
    }
};

var result = await manager.ConnectAsync(options, destroyCancellationToken);
if (!result.IsSuccessful)
    Debug.LogError($"连接失败：{result.Error.Message}");
```

#### `DisconnectAsync`

```csharp
IConvaiOperation<Unit> DisconnectAsync(CancellationToken ct = default)
```

优雅地断开房间会话。将在会话到达时完成 `已断开`.

***

### 对话控制

| 方法                                                                                          | 返回                       | 说明                                                                |
| ------------------------------------------------------------------------------------------- | ------------------------ | ----------------------------------------------------------------- |
| `SetConversationInputModeAsync(ConversationInputMode mode, CancellationToken ct = default)` | `IConvaiOperation<Unit>` | 在运行时切换房间的对话输入模式                                                   |
| `StartListening()`                                                                          | `void`                   | 开始麦克风采集。 `Audio.StartListeningAsync()` ，使用默认设备的快捷方式。              |
| `ToggleMicMute()`                                                                           | `bool`                   | 切换麦克风静音。返回新的静音状态。                                                 |
| `EnableAudioAndStartListening()`                                                            | `void`                   | 调用 `Audio.EnableAudioPlayback()` 然后开始监听。在 WebGL 上，任何音频交互之前都需要这样做。 |

***

### 直接 C# 事件

`ConvaiManager` 除了可通过 `事件`访问的类型化事件中心之外，还公开了三个直接的 C# 事件。当你需要轻量级会话状态通知，而不需要完整的事件中心或转发器设置时，可订阅这些事件。

| 事件               | 签名                     | 触发时        |
| ---------------- | ---------------------- | ---------- |
| `OnConnected`    | `Action`               | 会话到达 `已连接` |
| `OnDisconnected` | `Action`               | 会话到达 `已断开` |
| `OnError`        | `Action<SessionError>` | 会话遇到错误     |

{% hint style="info" %}
如需更丰富的会话状态数据（过渡上下文、参与者变化、空闲警告），请使用 `ConvaiSessionEventRelay` 或 `ConvaiManager.ActiveManager.Events`。以上直接事件刻意保持最小化——仅包含连接和错误。
{% endhint %}

***

### 所有权管理

使用这些方法来控制管理器拥有哪些角色和玩家，以及哪个角色是当前对话目标。

| 方法                                                               | 说明                                                       |
| ---------------------------------------------------------------- | -------------------------------------------------------- |
| `SetExplicitConversationTarget(ConvaiCharacter character)`       | 设置当前对话目标角色。传入 `null` 以清除。                                |
| `SetExplicitPlayer(ConvaiPlayer player)`                         | 将特定的 `ConvaiPlayer` 实例分配为受管理的玩家                          |
| `SetExplicitCharacters(IEnumerable<ConvaiCharacter> characters)` | 用提供的集合替换受管理的角色列表                                         |
| `RefreshReferences()`                                            | 重新扫描场景中的 `ConvaiCharacter` 是位于 `ConvaiPlayer` 实例以重建受管理集合 |

***

### 服务访问器模式

对于需要直接访问内部服务的高级场景， `ConvaiManager` 提供了 12 个类型化的 `TryGet*` 访问器。每个都会返回 `true` 并在成功时设置 `输出` 参数，或者在服务不可用时返回 `false` 。

{% hint style="info" %}
优先使用 `事件`, `音频`，以及 `转录文本` 外观封装属性来处理常见任务。该 `TryGet*` 访问器旨在用于高级集成和自定义工具。
{% endhint %}

```csharp
if (manager.TryGetMicrophoneDeviceService(out var micService))
{
    var devices = micService.GetAvailableDevices();
    // 填充设备选择器 UI
}
```

| 方法                                                                  | 服务类型                             | 常见用例                               |
| ------------------------------------------------------------------- | -------------------------------- | ---------------------------------- |
| `TryGetEventHub(out IEventHub)`                                     | `IEventHub`                      | 通过 `ConvaiEvents.Raw`访问原始事件总线；高级订阅 |
| `TryGetRoomConnectionService(out IConvaiRoomConnectionService)`     | `IConvaiRoomConnectionService`   | 底层连接生命周期控制                         |
| `TryGetRoomAudioService(out IConvaiRoomAudioService)`               | `IConvaiRoomAudioService`        | 直接音频服务访问（绕过 `ConvaiAudio` 外观封装）    |
| `TryGetAgentRegistry(out IAgentRegistry)`                           | `IAgentRegistry`                 | 查询已注册的角色和玩家                        |
| `TryGetSettingsPanelController(out IConvaiSettingsPanelController)` | `IConvaiSettingsPanelController` | 以编程方式打开/关闭设置面板                     |
| `TryGetRuntimeSettingsService(out IConvaiRuntimeSettingsService)`   | `IConvaiRuntimeSettingsService`  | 读取和写入运行时设置（音频音量、麦克风设备等）            |
| `TryGetMicrophoneDeviceService(out IMicrophoneDeviceService)`       | `IMicrophoneDeviceService`       | 枚举可用的麦克风设备；构建设备选择器 UI              |
| `TryGetPermissionService(out IConvaiPermissionService)`             | `IConvaiPermissionService`       | 请求平台麦克风权限（Android、iOS）             |
| `TryGetNotificationService(out IConvaiNotificationService)`         | `IConvaiNotificationService`     | 从你自己的脚本触发 SDK 通知                   |
| `TryGetPlayerInputService(out IPlayerInputService)`                 | `IPlayerInputService`            | 访问玩家输入状态和文本消息路由                    |
| `TryGetVisibleCharacterService(out IVisibleCharacterService)`       | `IVisibleCharacterService`       | 查询相机视锥内可见的角色                       |
| `TryGetTransportProvider(out ITransportProvider)`                   | `ITransportProvider`             | 访问传输层，用于诊断或自定义传输场景                 |

***

### SDK 版本

该 `ConvaiSDK` 静态类会公开 SDK 版本，用于条件功能检查。

```csharp
using Convai.Application;

Debug.Log($"Convai SDK {ConvaiSDK.Version}"); // 例如 "4.2.0"

if (ConvaiSDK.Version >= new System.Version(4, 2, 0))
{
    // 使用 4.2 中引入的功能
}
```

***

### 使用示例

#### 示例 1 — 在场景加载时带取消进行连接

一个工业安全模拟在场景加载时连接到 Convai，并通过 `destroyCancellationToken` 将其绑定到组件生命周期，因此如果场景在尝试中途卸载，连接操作会干净地取消。

{% code title="SceneConnector.cs" %}

```csharp
using Convai.Runtime.Core.Async;
using Convai.Runtime.Facades;
using UnityEngine;

public class SceneConnector : MonoBehaviour
{
    private async void Start()
    {
        var manager = ConvaiManager.ActiveManager;
        if (manager == null) return;

        try
        {
            var session = await manager.ConnectAsync(destroyCancellationToken);
            Debug.Log($"已连接。会话：{session.RoomId}");
        }
        catch (ConvaiOperationException ex)
        {
            Debug.LogError($"连接失败：{ex.Message}");
        }
        catch (System.OperationCanceledException) { /* 场景已卸载 */ }
    }
}
```

{% endcode %}

#### 示例 2 — 在触发区域进入时切换对话目标

一个企业入职模拟在房间中有多个 AI 顾问。当学习者走进某个顾问的区域时，该顾问就会成为当前对话目标。

{% code title="AdvisorZone.cs" %}

```csharp
using Convai.Runtime.Components;
using Convai.Runtime.Facades;
using UnityEngine;

public class AdvisorZone : MonoBehaviour
{
    [SerializeField] private ConvaiCharacter _advisor;

    private void OnTriggerEnter(Collider other)
    {
        if (!other.CompareTag("Player")) return;
        ConvaiManager.ActiveManager?.SetExplicitConversationTarget(_advisor);
    }

    private void OnTriggerExit(Collider other)
    {
        if (!other.CompareTag("Player")) return;
        ConvaiManager.ActiveManager?.SetExplicitConversationTarget(null);
    }
}
```

{% endcode %}

#### 示例 3 — 麦克风设备选择器 UI

一个交互式体验允许用户在会话开始前选择偏好的麦克风，使用 `IMicrophoneDeviceService` 来枚举可用设备。

{% code title="MicrophonePicker.cs" %}

```csharp
using Convai.Runtime.Facades;
using System.Linq;
using TMPro;
using UnityEngine;

public class MicrophonePicker : MonoBehaviour
{
    [SerializeField] private TMP_Dropdown _deviceDropdown;

    private void Start()
    {
        var manager = ConvaiManager.ActiveManager;
        if (manager == null || !manager.TryGetMicrophoneDeviceService(out var micService))
            return;

        var devices = micService.GetAvailableDevices();
        _deviceDropdown.ClearOptions();
        _deviceDropdown.AddOptions(devices.Select(d => d.Name).ToList());
    }
}
```

{% endcode %}

***

### 故障排查

| 症状                             | 可能原因                                    | 修复                                                                               |
| ------------------------------ | --------------------------------------- | -------------------------------------------------------------------------------- |
| `ActiveManager` 返回 `null` 在运行时 | `ConvaiManager` 不在场景中，或在引导完成前被访问        | 通过 **Convai → Create Manager**；使用前先判空；订阅 `OnConnected` 而不是在 `Awake` 或 `OnEnable` |
| `TryGet*` 返回 `false`           | 服务不可用或管理器尚未完全引导                         | 检查 `IsBootstrapped` 之前调用；在 `OnConnected` 触发                                      |
| `ConnectAsync` 保持 `运行中` 无限期地   | API 密钥无效、网络不可达，或者 `ConvaiSettings` 资源缺失 | 在以下位置验证 API 密钥 **Convai → Settings**；使用超时 `CancellationToken` 来暴露失败              |
| `RefreshReferences` 未找到动态生成的角色 | 在场景加载后实例化的角色不会被自动发现                     | 调用 `RefreshReferences()` 在实例化后，或使用 `SetExplicitCharacters()` 直接注册它们              |

***

### 下一步

有关音频和麦克风脚本，请参见 [音频 API](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/scripting-reference/audio-api.md)。有关 C# 中的连接状态和错误事件，请参见 [会话事件](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/scripting-reference/session-events.md)。有关异步操作消费模式，请参见 [异步模式](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/scripting-reference/async-patterns.md).


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.convai.com/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/scripting-reference/convaimanager-api.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
