> 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/ui-and-presentation/customizing-ui-components.md).

# 自定义 UI 组件

使用角色可见性过滤器或预制件替换来重新设计或替换内置的转录、通知和设置 UI。

两条扩展路径让你无需替换 SDK 的数据管道即可自定义其场景级 UI。角色可见性过滤控制哪些角色的转录内容会到达当前显示。视觉自定义则替换用于渲染这些转录、通知和设置控件的预制体。

若想在没有自定义 UI 的情况下使用轻量级转录回调，请使用 `ITranscriptListener`。若要实现一个完整的自定义转录显示，用于替换内置聊天或字幕面板，请使用 `ITranscriptUI`。这两个接口都在以下位置有文档说明： [转录 UI](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/ui-and-presentation/transcript-ui.md).

### 角色可见性过滤

控制哪些角色的转录内容会被 `TranscriptUIController` 路由到活动 UI——这对多角色场景至关重要，因为同时出现的转录会造成混乱。

**基类：** `TranscriptFilterBase` （SDK 提供，位于 `SDK/Runtime/Presentation/Services/Utilities/`)

* 如果不存在，会自动添加一个 `SphereCollider` （半径 `5f`，触发器模式）到 `GameObject`
* 维护 `CharactersInsideColliderList` ，通过 `OnTriggerEnter` / `OnTriggerExit` 回调
* 与 `IVisibleCharacterService` 集成——会在 `ConvaiManager` 启动时自动解析
* 放在玩家 `GameObject` 或其子对象上

**两个可直接使用的实现** （位于 `SamplesShared/Scripts/UI/Utilities/` ——修改前请先复制）：

#### `SingleCharacterFilter`

跟踪 **玩家视野锥内最近的角色**.

* 最适合有多个角色的字幕模式
* 玩家只能看到其面向角色的转录内容
* 默认视野锥：总计 90°（前方 45° 内的任意角色）
* 通过实现 `IVisionConeProvider` 来覆盖视野锥角度。该接口定义在 `ProximityCharacterFilter.cs` （命名空间 `Convai.Sample.UI.Utilities`，SamplesShared 层）：

```csharp
// 定义在 ProximityCharacterFilter.cs 中——命名空间 Convai.Sample.UI.Utilities
public interface IVisionConeProvider
{
    float VisionConeAngle { get; }
}
```

#### `ProximityCharacterFilter`

跟踪 **半径和视野锥内的所有角色**.

* 最适合群组对话的聊天模式
* 可同时显示多个角色的转录内容
* 与 `SingleCharacterFilter`

**场景设置检查清单：**

* [ ] 添加 `SingleCharacterFilter` 或 `ProximityCharacterFilter` 到玩家 `GameObject`
* [ ] 确保 `Rigidbody` 存在于玩家或角色上（触发器回调所必需）
* [ ] `ConvaiManager` 自动解析 `IVisibleCharacterService` 在过滤器启动时
* [ ] 在 Play Mode 中向角色靠近和远离进行测试

{% hint style="warning" %}
`SingleCharacterFilter` 和 `ProximityCharacterFilter` 是位于 `SamplesShared`中的参考实现。修改前请将它们复制到你自己的程序集里——对 `SamplesShared` 脚本会在 SDK 更新时被覆盖。
{% endhint %}

### 视觉自定义

#### 聊天消息气泡

`ChatTranscriptUI` 会从其 Inspector 字段中实例化角色和玩家消息预制体。要重新样式化：

1. 从 `Prefabs/TranscriptUI/` ，位于 <code class="expression">space.vars.sdk\_package\_id</code> 包中复制默认气泡
2. 重新样式化复制件（颜色、字体、背景、布局）
3. 分配给 `characterMessagePrefab` 或 `playerMessagePrefab` 在 `ChatTranscriptUI`

你的替换预制体必须包含一个 `ChatMessageBubble` 组件，并连接好这些字段：

| 字段          | 类型                | 说明      |
| ----------- | ----------------- | ------- |
| `senderUI`  | `TextMeshProUGUI` | 显示说话者名称 |
| `messageUI` | `TextMeshProUGUI` | 显示转录文本  |

在 `ChatMessageBubble`:

| 方法                              | 说明                       |
| ------------------------------- | ------------------------ |
| `上的可用样式方法`                      | SetSender(string sender) |
| `设置发送者显示名称`                     | 覆盖自动分配的发送者名称颜色           |
| `SetMessage(string message)`    | 设置完整消息文本                 |
| `AppendMessage(string message)` | 将文本追加到当前消息（流式传输时使用）      |

#### 通知预制体

`UINotificationController` 会实例化 `UINotification` 预制体，来源于其 `uiNotificationPrefab` 字段。要重新样式化：

1. 复制 `Notification.prefab` 来自 `Prefabs/Notifications/` ，位于 <code class="expression">space.vars.sdk\_package\_id</code> 包中复制默认气泡
2. 重新样式化复制件
3. 分配给 `uiNotificationPrefab` 在 `UINotificationController`

必需 `UINotification` 引用：

| 字段                          | 类型                | 说明     |
| --------------------------- | ----------------- | ------ |
| `notificationRectTransform` | `RectTransform`   | 用于滑入位置 |
| `notificationIcon`          | `Image`           | 图标显示   |
| `notificationTitleText`     | `TextMeshProUGUI` | 标题     |
| `notificationMessageText`   | `TextMeshProUGUI` | 正文     |

#### 设置面板视图

实现 `ISettingsPanelView` 并连接到 `SettingsPanelPresenter` ，即可实现完全自定义的设置 UI。Presenter 负责处理所有业务逻辑——你的视图只负责渲染和输入事件。

```csharp
// 将你的自定义视图绑定到现有 presenter
settingsPanelPresenter.Bind(myCustomView);

// 当视图销毁时解除绑定
settingsPanelPresenter.Unbind();
```

### 使用示例

#### 多角色字幕焦点

一个包含多个 AI 角色（医生、护士、病人）的医疗模拟使用 `SingleCharacterFilter` 在受训者身上，使字幕显示自动切换到他们面向的 AI 角色。将该组件添加到玩家 `GameObject`，验证一个 `Rigidbody` 已存在，并保留默认的 90° 视野锥。运行时，当受训者在角色之间转身时，当前字幕会自动切换到他们正前方的角色，无需手动干预。

#### 自定义通知皮肤

一个军事训练模拟将默认通知预制体替换为与模拟 UI 风格一致的 HUD 警报。复制默认通知预制体，将其重新样式化为右上角状态指示器，并将其分配给 `UINotificationController.uiNotificationPrefab`。运行时，所有系统和会话错误警报都会以项目的视觉风格显示，而无需更改任何通知逻辑。

### 故障排除

| 症状                                  | 可能原因                                                           | 修复方法                                                            |
| ----------------------------------- | -------------------------------------------------------------- | --------------------------------------------------------------- |
| `TranscriptFilterBase` 未跟踪角色        | 没有 `Rigidbody` 位于玩家或角色上                                        | 添加一个 `Rigidbody` 到每个角色-玩家对的至少一侧                                 |
| `SingleCharacterFilter` 跟踪了错误的角色    | Player `GameObject` 未通过 `GetComponentInParent<ConvaiPlayer>()` | 将过滤器放在玩家上 `GameObject` 或注入 `IPlayerInputService` ，通过 `Inject()` |
| Custom `ISettingsPanelView` 未收到保存回调 | 视图未绑定到 presenter                                               | 调用 `settingsPanelPresenter.Bind(myCustomView)` 在 presenter 可用之后 |
| 替换后的气泡预制体不显示文本                      | `senderUI` 或 `messageUI` 未分配到 `ChatMessageBubble`              | 连接好两个 `TextMeshProUGUI` 预制体 Inspector 中的引用                      |
| 自定义通知预制体未出现                         | `uiNotificationPrefab` 在 `UINotificationController` 仍然指向默认项    | 将你重新样式化后的预制体分配给 `uiNotificationPrefab` 字段                       |

### 下一步

{% content-ref url="/pages/49fed70bb2b468bcc6348096af1fc53fdb0656ce" %}
[转录 UI](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/ui-and-presentation/transcript-ui.md)
{% endcontent-ref %}

{% content-ref url="/pages/6695eb978b08dbf5023b367d38af0912574c4f52" %}
[聊天和字幕模式](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/ui-and-presentation/transcript-ui/chat-and-subtitle-modes.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 by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.convai.com/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/ui-and-presentation/customizing-ui-components.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

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.
