> 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/notification-system.md).

# 通知系统

添加吐司式提示以自动显示会话错误，并使用通知资源从代码中触发你自己的场景内警报。

通知系统会在你的场景中显示临时的、吐司样式的弹出提示。它会自动处理会话错误警报——当 Convai 报告连接或身份验证错误时，系统会将错误代码映射到一个通知资源并将其排队显示。你也可以在会话期间的任何时刻从代码中触发自定义通知。

屏幕上最多可同时显示三个通知。额外的通知会在内部排队，并在有空间可用时显示。

关于字段级参考，请参见 `SONotification`, `SONotificationGroup`, `UINotificationController`，以及 `SONotificationErrorMap`的 SDK 方法，请参阅 [通知系统参考](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/ui-and-presentation/notification-system/notification-system-reference.md).

### 通知系统的工作方式

下图展示了系统的数据流：

```mermaid
graph TD
    A[IConvaiNotificationService] -->|RequestNotification| B[NotificationHandler]
    B -->|通过 SONotificationGroup 解析| C[UINotificationController]
    C -->|3 个的池| D[UINotification]
    E[会话错误] -->|SONotificationErrorMap| A
    F[你的脚本] -->|RequestNotification| A
    G[运行时设置\nNotificationsEnabled=false] -->|RuntimeSettingsNotificationApplier| A
```

`IConvaiNotificationService` 是所有通知请求的唯一入口点。 `NotificationHandler` 使用 `SONotificationGroup`按 ID 解析通知资源，然后将其传递给 `UINotificationController`，后者管理一个可重用的 `UINotification` 元素池。会话错误会通过 `SONotificationErrorMap` 自动将错误代码映射到通知资源。

### 将通知系统添加到你的场景中

{% stepper %}
{% step %}

#### 创建你的通知资源

为每种警报类型创建一个 `SONotification` 资源。为每个资源分配一个唯一的 `Id` 字符串，使其与错误映射或脚本引用的内容一致。
{% endstep %}

{% step %}

#### 创建并填充一个通知组

创建一个 `SONotificationGroup` 资源。将所有 `SONotification` 资源添加到其 `soNotifications` 数组中。保存到 `Assets/Resources/SONotificationGroup.asset`.
{% endstep %}

{% step %}

#### 添加 NotificationSystem 预制体

拖入 `NotificationSystem.prefab` 到你的场景中。你可以在以下位置找到它： `Prefabs/Notifications/NotificationSystem.prefab` ，位于 <code class="expression">space.vars.sdk\_package\_id</code> 包中。该预制体同时包含 `NotificationHandler` 和 `UINotificationController`.

在 `NotificationHandler`的 Inspector 中，将你的 `SONotificationGroup` 资源分配给 `notificationGroup` 字段。
{% endstep %}

{% step %}

#### 配置时间参数（可选）

调整 `UINotificationController` Inspector 字段以匹配你项目的视觉节奏。默认值适合作为大多数场景的起点。

当设置正确时，触发通知会使面板从 `activeNotificationPos`滑入。滑入动画持续 `slipDuration` 秒（默认 `0.3`s）。
{% endstep %}
{% endstepper %}

### 从代码中触发通知

访问权限 `IConvaiNotificationService` 到 `ConvaiManager`:

```csharp
using Convai.Runtime.Components;
使用 Convai.Runtime.Presentation.Views.Notifications;
using UnityEngine;

public class ScenarioNotifier : MonoBehaviour
{
    [SerializeField] private SONotification _stepCompleteNotification;
    [SerializeField] private SONotification _failureNotification;

    public void NotifyStepComplete()
    {
        if (ConvaiManager.ActiveManager.TryGetNotificationService(out var service))
            service.RequestNotification(_stepCompleteNotification);
    }

    public void NotifyFailure()
    {
        if (ConvaiManager.ActiveManager.TryGetNotificationService(out var service))
            service.RequestNotification(_failureNotification);
    }

    public void DismissAll()
    {
        if (ConvaiManager.ActiveManager.TryGetNotificationService(out var service))
            service.DismissNotification();
    }
}
```

`DismissNotification()` 会立即清除当前显示的所有通知，包括任何正在进行的动画。

{% hint style="info" %}
通知服务会强制执行每个通知 **10 秒冷却时间** 。 `Id`在 10 秒内重复的请求会被静默丢弃。这可以防止错误洪泛占满屏幕。冷却时间会在 10 秒后自动重置。
{% endhint %}

### 自动错误到通知映射

会话错误会通过 `SONotificationErrorMap`自动触发通知。该资源使用按顺序排列的规则列表，将错误代码字符串映射到 `SONotification` 资源。 **首个匹配规则优先生效**.

**创建：** 右键 → **创建 → Convai → Notification System → Session Error Map**

保存到 `Assets/Resources/SONotificationErrorMap.asset` 以便自动加载。

完整的 `SessionErrorNotificationRule` 字段参考，请参见 [通知系统参考](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/ui-and-presentation/notification-system/notification-system-reference.md).

**示例规则配置：**

| ErrorPattern  | MatchType | Notification                   |
| ------------- | --------- | ------------------------------ |
| `AUTH_FAILED` | `精确的`     | `Notification_AuthError`       |
| `CONNECTION_` | `Prefix`  | `Notification_ConnectionError` |
| `RATE_LIMIT`  | `精确的`     | `Notification_RateLimit`       |

规则按从上到下的顺序进行评估。请将更具体的规则放在更宽泛的前缀匹配之上。

### 遵循通知运行时设置

通知系统会遵循内置设置面板中的 **Notifications** 开关。当用户禁用通知时：

* 任何当前显示的通知都会立即关闭
* 后续的 `RequestNotification` 调用会被静默忽略
* 日志会记录： `“无法发送通知，因为运行时设置中已禁用通知。”`

要通过脚本切换通知：

```csharp
if (ConvaiManager.ActiveManager.TryGetRuntimeSettingsService(out var settings))
{
    settings.Apply(new ConvaiRuntimeSettingsPatch { NotificationsEnabled = false });
}
```

### 使用示例

#### 企业入职——步骤完成提醒

企业入职模拟会在受训者每次与 AI 人力资源代表完成一个必需的对话检查点时通知他们：

* 创建一个 `SONotification` 带有 `Id = "checkpoint-complete"`的资源、一个对勾图标，以及消息“检查点已完成。继续下一个主题。”
* 调用 `service.RequestNotification(checkpointNotification)` 来自检查点评估处理器
* 通知会显示 4 秒，然后在不中断正在进行的对话的情况下关闭
* 如果评估逻辑多次触发，10 秒冷却时间可防止重复通知

在运行时，每次检查点完成都会产生一个简短的确认提示，出现后会自动清除，而不会暂停对话。

#### 防火墙受限环境中的连接错误

在公司网络上运行的培训模拟在连接失败时需要信息明确的错误消息：

* 创建一个 `SONotificationErrorMap` 规则如下： `ErrorPattern = "CONNECTION_"`, `MatchType = Prefix`
* 设置 `Notification` 映射到一个包含消息“连接失败。请联系 IT 支持，分机 4400。”的资源
* 错误映射会在任何 `CONNECTION_` 以前缀开头的错误上自动触发——无需额外代码

在运行时，任何连接失败都会产生清晰、可操作的通知，而不是静默失败。

#### 多场景重置——在场景切换时关闭全部通知

多场景模拟在场景之间切换时会清除任何残留通知：

```csharp
public void TransitionToNextScenario()
{
    if (ConvaiManager.ActiveManager.TryGetNotificationService(out var service))
        service.DismissNotification();

    LoadNextScenario();
}
```

在运行时，调用 `DismissNotification()` 会在下一个场景加载前立即清屏，确保过时的警报不会出现在错误的上下文中。

### 故障排除

| 症状                                                                    | 可能原因                                                                  | 修复方法                                                                                                                  |
| --------------------------------------------------------------------- | --------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- |
| 不会出现任何通知；控制台显示 `“[NotificationHandler] 无法解析 SONotificationGroup 资源。”` | 组资源不在 `Resources/`                                                    | 保存到 `Assets/Resources/SONotificationGroup.asset`                                                                      |
| 控制台显示 `“[NotificationHandler] 未找到 UINotificationController 且未设置预制体。”` | `NotificationSystem.prefab` 不在场景中或 `notificationControllerPrefab` 未分配 | 将预制体添加到场景中，或在 `NotificationHandler` Inspector                                                                         |
| 控制台显示 `“[NotificationHandler] 通知服务不可用；通知将延迟到服务初始化后再处理。”`              | 通知在 `ConvaiManager` 完成初始化之前触发                                         | 将通知调用延迟到 `ConvaiManager.IsInitialized` 是 `true`                                                                       |
| 控制台显示 `“[NotificationHandler] 通知组中没有注册 ID 为 {id} 的通知”`                | Notification `Id` 中的脚本与 `SONotificationGroup`                         | 检查 `Id` 字段，在 `SONotification` 资源中的任何资源都不匹配，并更新该组                                                                      |
| 控制台显示 `“[NotificationHandler] UINotificationController 为空，无法显示通知。”`   | 控制器引用丢失或未在场景中找到                                                       | 验证 `NotificationSystem.prefab` 在场景中                                                                                   |
| 已请求通知但未显示；控制台无错误                                                      | 此通知正处于 10 秒冷却期                                                        | 等待 10 秒，或使用带有唯一 `Id`                                                                                                  |
| 与设置面板交互后通知已禁用                                                         | 用户切换为 **Notifications** 关闭                                            | 可通过设置面板重新启用，或通过 `IConvaiRuntimeSettingsService.Apply(new ConvaiRuntimeSettingsPatch { NotificationsEnabled = true })` |
| 第 4 个通知未立即显示                                                          | 最多同时 3 个——第 4 个已排队                                                    | 预期行为——当一个活动通知关闭时，它就会立即显示                                                                                              |

### 下一步

有了通知系统，你可以在不打断 AI 对话的情况下呈现连接错误、场景事件和自定义警报。为了让用户控制通知是否显示，请接入设置面板。若要重新设计通知视觉效果，请参见自定义 UI 组件。

{% content-ref url="/pages/dddf624ca0ae7ec32afa0c9e601f2cb7c7ab2b6a" %}
[设置面板](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/ui-and-presentation/settings-panel.md)
{% endcontent-ref %}

{% content-ref url="/pages/5f60eaa8d444f5ee8a995392852da827736d3b54" %}
[自定义 UI 组件](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/ui-and-presentation/customizing-ui-components.md)
{% endcontent-ref %}

{% content-ref url="/pages/caa7ca5d0d83b53a1e0bc946efa57288e237a693" %}
[通知系统参考](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/ui-and-presentation/notification-system/notification-system-reference.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/notification-system.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.
