> 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/overview/convai-unity-sdk-architecture.md).

# Convai Unity SDK 架构

了解 Convai Unity SDK 的四层架构——运行时、房间、代理和模块——以及每一层的职责。

SDK 分为四个层级：运行时、房间、代理和模块。作为开发者，你主要与代理层（角色和玩家组件）以及模块层（按需启用的功能模块）交互。运行时层和房间层以最少的配置要求处理连接和服务引导。

### 系统图

```mermaid
graph TD
    subgraph RT["运行时层"]
        CM["ConvaiManager\n（组合根，服务枢纽）"]
        CS["ConvaiSDK\n（版本元数据）"]
    end

    subgraph RM_TIER["房间层"]
        RM["ConvaiRoomManager\n（连接 · 音频 · 轮流发言）"]
    end

    subgraph AG["代理层"]
        CC["ConvaiCharacter × N\n（会话 · 文本记录 · 事件）"]
        CP["ConvaiPlayer\n（身份 · 文本输入）"]
    end

    subgraph ML["模块层（每个角色按需启用）"]
        方向 LR
        口型同步
        情绪
        视觉
        叙事
        对话动画
        面部动画
        注视
        注意力
        对话流程
        具身化
    end

    CM --> RM
    RM --> CC
    RM --> CP
    CC -.->|模块附加到| ML
```

虚线从 `ConvaiCharacter` 到模块层表示模块是可选组件，你将它们添加到与角色相同的 GameObject 上——基础对话不需要它们。

### 运行时层

运行时层会在你的场景加载时启动，并为其下方的一切提供服务。

`ConvaiSDK` 是一个静态类，公开 SDK 版本（`ConvaiSDK.Version`）。你很少直接引用它。

`ConvaiManager` 是组合根。它是一个单例（`ConvaiManager.ActiveManager`）并标记为 `[DefaultExecutionOrder(-1100)]` 因此它会在其他场景对象之前初始化。它负责：

* **服务访问器** — `TryGet` 适用于每个内部服务的 TryGet 方法（麦克风、音频、代理注册表、通知、设置面板等）
* **高层封装** — `ConvaiManager.Audio`, `ConvaiManager.Transcripts`, `ConvaiManager.Events` 用于最常见的脚本任务
* **连接控制** — `ConnectAsync()`, `DisconnectAsync()`, `SetConversationInputModeAsync()`
* **代理引用** — `Characters`, `Player`, `ActiveConversationCharacter`

{% hint style="info" %}
大多数集成代码只需要 `ConvaiManager.ActiveManager` 以及角色自身的事件。 `TryGet` 服务访问器适用于你替换或扩展内部服务的高级用例。
{% endhint %}

### 房间层

`ConvaiRoomManager` 负责与 Convai 的实时连接。一个 `ConvaiRoomManager` 每个场景一个，由 `ConvaiManager`.

它负责：

* **房间连接生命周期** —— 连接、断开连接、重新连接
* **麦克风采集** —— 启动和停止音频输入，静音控制
* **轮流发言模式** —— 免手操作（`ConversationInputMode.HandsFree`）或按住说话（`ConversationInputMode.PushToTalk`)
* **动态上下文传输** —— 在运行时向 Convai 发送状态更新和事件
* **音频播放协调** —— 启用远程角色音频、WebGL 用户手势处理

`ConvaiRoomManager` 提供用于诊断、音频、所有权和连接管理的协调器。这些可通过 `ConvaiManager.ActiveManager.TryGetRoomConnectionService()` 进行访问，以便进行高级脚本编写。

### 代理层

代理层包含你放置在场景 GameObject 上的组件。

#### ConvaiCharacter

添加 `ConvaiCharacter` 添加到每个 NPC 或代理 GameObject 上。每个角色一个组件。它负责：

* 角色 ID — 来自你的 Convai 仪表板的唯一 ID
* 会话状态 — `已断开`, `连接中`, `已连接`, `正在重新连接`, `正在断开连接`, `错误`
* 对话生命周期 — `StartConversationAsync()`, `StopConversationAsync()`, `ToggleSpeech()`
* 文本记录和事件回调 — `OnTranscriptReceived`, `OnEmotionChanged`, `OnActionsReceived`, `OnSpeechStarted`, `OnSpeechStopped`, `OnCharacterReady`
* 动作配置 — 通过 `ConvaiActionConfigSource` 组件

`ConvaiCharacter` 可以在 Inspector 中内联配置，或者通过可复用的 `ConvaiCharacterProfile` ScriptableObject 资源。

#### ConvaiPlayer

添加 `ConvaiPlayer` 添加到你的玩家 GameObject。每个场景一个是标准做法。它负责：

* 用于文本记录归属的玩家显示名称和名称标签颜色
* 文本消息发送 — `SendTextMessage(string message)`
* 运行时身份覆盖 — `SetRuntimeDisplayName(string displayName)`

{% hint style="warning" %}
`ConvaiPlayer.PlayerId` 是用于文本记录 UI 归属的本地显示标识符。它不是用于长期记忆跟踪的服务器生成的说话者 ID。
{% endhint %}

### 模块层

模块是你添加到与 `ConvaiCharacter` （或 `ConvaiRoomManager` 相同 GameObject 上的可选 Unity 组件（例如 Vision）。每个模块都是独立的——只添加项目需要的部分。

| 模块        | 作用                                                              |
| --------- | --------------------------------------------------------------- |
| LipSync   | 由音频播放驱动的实时 BlendShape 嘴部动画；支持 ARKit、MetaHuman 和 CC4 Extended 映射 |
| 情绪        | 接收 Convai 情绪信号，对其进行平滑处理，并分发到 BlendShape 或 Animator 参数绑定         |
| 视觉        | 将相机、摄像头或 Meta Quest 透视画面发布给 Convai，以实现多模态感知                     |
| Narrative | 通过与对话流程相关联的触发事件，管理故事章节的推进                                       |
| 对话动画      | 在对话期间驱动四层动画器堆栈（基础待机、蒙版叠层、身体说话、头部说话）                             |
| 面部动画      | 在运行时播放面部动画片段，并与口型同步和情绪输出进行混合合成                                  |
| 注视        | 将眼睛和头部执行器朝向对话伙伴和注意目标进行混合调整                                      |
| 注意力       | 解析加权焦点目标，为 Gaze 模块提供注视方向                                        |
| 对话流程      | 将对话事件流桥接到逐帧对话状态（Idle、Speaking、Reacting 等）                       |
| 实体化       | 用于实体存在和行为模块的基础行为配置文件与生命周期管理                                     |

`对话流程` 在 `ConvaiCharacter` 初始化时，会在运行时自动配置。所有其他模块—— `LipSync`, `情绪`, `视觉`, `Narrative`, `对话动画`, `面部动画`, `注视`, `注意力`，以及 `实体化` ——都是按需启用的。

### 配置模型

每个主要组件都支持两种配置模式，可在 Inspector 中选择。

{% tabs %}
{% tab title="内联" %}
值直接在 Inspector 中设置于组件上。这是默认模式，适用于大多数场景——无需额外资源。
{% endtab %}

{% tab title="资源" %}
值来自可复用的 `ConvaiCharacterProfile` 或 `ConvaiRoomManagerProfile` ScriptableObject。当你想在多个场景或预制体变体之间共享默认值，或者需要在不修改单个预制体的情况下切换角色行为时使用。
{% endtab %}
{% endtabs %}

### 下一步

{% content-ref url="/pages/c8899f56d4e857b17f25df9ab7da1ed0213d1d5f" %}
[功能地图](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/overview/feature-map.md)
{% endcontent-ref %}

{% content-ref url="/pages/5ea68df21c8a54f95779af92056a9ab831531be5" %}
[快速开始](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/getting-started.md)
{% endcontent-ref %}


---

# 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, and the optional `goal` query parameter:

```
GET https://docs.convai.com/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/overview/convai-unity-sdk-architecture.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
