> 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/advanced-topics/extending-the-sdk.md).

# 运行时模块系统

Convai Unity SDK 基于一个模块系统构建，该系统为可选功能——口型同步、情绪、视觉、叙事设计——在运行时生命周期中提供了明确的位置。你可以使用同一系统添加自己的模块：它们会接收相同的启动序列，访问相同的服务，并且可以与其他模块共享接口。

### 你需要自定义模块吗？

当你需要以下行为时，自定义模块是合适的工具：

* **参与 SDK 运行时生命周期** ——与 SDK 一起启动和停止，而不是独立运行
* **与其他 SDK 模块共享服务** ——例如，提供一个 `IAudioAnalysisService` ，由情绪模块或你自己的代码使用
* **响应 SDK 域事件** ——角色语音状态、情绪变化、动作触发
* **集成硬件或平台系统** ——触觉设备、生物识别传感器、计分引擎

以下情况不需要自定义模块：

* 在 MonoBehaviour 中响应 SDK 事件——直接通过 `context.Events` 从一个 `IInjectable` 组件中订阅，或者使用 `ConvaiCharacter`
* 对角色的简单自定义行为——向角色的 GameObject 添加一个 MonoBehaviour
* 从你自己的脚本调用 Convai REST API——使用 `ConvaiManager.ActiveManager` 直接

如果不确定，先从 `MonoBehaviour` 开始，仅在需要生命周期集成时再升级到 `IConvaiModule` 。

### 什么是模块

模块是一个实现了 `IConvaiModule`的类。它：

* 具有一个稳定的 `ModuleId` 字符串（按约定是唯一、小写、以连字符分隔——例如， `"my-company.haptic-feedback"`).
* 通过 `RequiredModules` 声明对其他模块的依赖，并通过 `RequiredServices`.
* 声明对运行时服务的依赖 **参与运行时生命周期：**.
* 可通过 `IModuleContext.ProvideModuleService<T>()`.

向其他模块暴露类型化服务。模块系统会自动处理启动顺序——模块会按照依赖顺序启动，并按相反顺序停止。

### 模块生命周期

生命周期包含五种状态。 `RegisterAsync` 会在任何 `StartAsync` 调用之前对所有模块运行，使每个模块在任何模块开始主动处理之前都有一个保证的时间窗口来注册服务。

```mermaid
stateDiagram-v2
    [*] --> Registered : RegisterAsync()
    Registered --> Started : StartAsync()
    Started --> Paused : PauseAsync(reason)
    Paused --> Started : ResumeAsync()
    Started --> Stopped : StopAsync()
    Paused --> Stopped : StopAsync()
    Stopped --> [*]
```

有关完整的生命周期方法契约和实现示例，请参见 [实现自定义模块](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/advanced-topics/implement-a-custom-module.md).

### 安全扩展点和内部 API

仅使用下面列出的公共扩展点。内部类型和平台特定层可能会在不通知的情况下更改。

#### 安全扩展点

| 内容      | 方式                                                                     |
| ------- | ---------------------------------------------------------------------- |
| 自定义模块行为 | 实现 `IConvaiModule` 并通过 `RegisterModule()` 或 `AddModule()`              |
| 模块间服务   | `ProvideModuleService<T>()` / `TryGetModuleService<T>()`               |
| 自定义凭据   | 重写 `CreateRuntimeBuilder()` 并调用 `builder.UseConfig()`                  |
| 自定义身份   | `SetEndUserIdentityProvider()` / `SetEndUserMetadataProvider()`，或构建器   |
| 自定义持久化  | 重写 `CreateRuntimeBuilder()` 并调用 `builder.UsePersistence()`             |
| 角色级组件集成 | 实现 `IInjectable<IConvaiCharacterDependencies>` 在角色层级中的 MonoBehaviour 上 |
| 事件订阅    | `IEventHub.Subscribe<T>()` / `Unsubscribe<T>()`                        |
| 日志路由    | `ConvaiLogger.RegisterSink(ILogSink)`                                  |

#### 内部 API——不要覆盖

| 区域                           | 原因                                 |
| ---------------------------- | ---------------------------------- |
| `ConvaiRuntime` 内部           | 按设计为私有；可能在不通知的情况下更改                |
| 传输层（`ITransportProvider` 实现） | 特定于平台；覆盖会破坏平台支持                    |
| RTVI 协议处理器（`RTVIHandler`)    | 序列化格式与 Convai 的后端绑定——任何覆盖都会导致协议不同步 |
| `ConvaiRoomManager` 内部       | 房间协调器内部不是扩展点                       |
| 超出 `RequiredModules`         | 拓扑排序是自动的；不要依赖注册顺序                  |

{% hint style="warning" %}
不要通过反射访问内部类型，也不要绕过构建器注入依赖。SDK 内部会在不同版本之间变化——绕过公共 API 的代码在升级时会无预警地失效。
{% endhint %}

### 下一步

{% content-ref url="/pages/c94f3576730a705ef8d7adec01d712a12612b542" %}
[实现自定义模块](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/advanced-topics/implement-a-custom-module.md)
{% endcontent-ref %}

{% content-ref url="/pages/0bd691fc4d8a06b0dbafd0f28b11f39be6f57f9a" %}
[事件系统](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/core-concepts/event-system.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:

```
GET https://docs.convai.com/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/advanced-topics/extending-the-sdk.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.
