> 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 组件

两种扩展路径让你在不替换其数据管线的情况下自定义 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` 在游戏中通过向角色走近和远离来测试
* [ ] 和

{% hint style="warning" %}
`SingleCharacterFilter` 是位于 `ProximityCharacterFilter` 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)`      | 设置发送者显示名称             |
| `SetSenderColor(Color color)`   | 覆盖自动分配的发送者名称颜色        |
| `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` 跟踪到了错误的角色 | 玩家 `GameObject` 未通过以下方式找到： `GetComponentInParent<ConvaiPlayer>()` | 将过滤器放在玩家上 `GameObject` 或注入 `IPlayerInputService` 通过 `Inject()`  |
| 自定义 `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 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/ui-and-presentation/customizing-ui-components.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.
