> 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/features/narrative-design/troubleshooting-and-diagnostics.md).

# 排查叙事设计问题

大多数 Narrative Design 问题属于三类之一：触发器未触发、章节事件没有响应，或者后端获取失败。本页将涵盖这三种情况，首先介绍内置状态系统，位于 `ConvaiNarrativeDesignTrigger` 并逐步排查最常见的 Inspector 错误配置。

### 第一线排查

当出现问题时，请先按这份检查清单排查，再去查看具体症状。大多数问题会在第 2 或第 3 步解决。

{% stepper %}
{% step %}

#### 检查触发器上的 CurrentStatus

选择 `ConvaiNarrativeDesignTrigger` 在 Inspector 中的 GameObject。 **当前状态** 显示在组件顶部。除 `就绪` 之外的任何值都会立即告诉你触发器正在等待什么——请参阅下面的 TriggerStatus 参考表以获取解决方案。
{% endstep %}

{% step %}

#### 启用诊断并重现问题

在 Trigger 组件中启用 **启用诊断**。按下 Play 并重复应当触发触发器的操作。每次状态转换——进入/退出区域、队列开始、检测到角色就绪、发送触发器——都会记录到 Console。按从上到下的顺序阅读日志，找出链路在哪一步中断。

```csharp
// 或通过代码启用
trigger.SetDiagnosticsEnabled(true);
```

{% endstep %}

{% step %}

#### 验证角色 ID 和 API 密钥

打开 **编辑 > 项目设置 > Convai SDK** 并确认 API 密钥已存在。选中你的角色 GameObject，并确认 **角色 ID** 上的字段 `ConvaiCharacter` 不为空。如果其中任何一项缺失，从触发器的角度看，获取操作和会话连接都会静默失败。
{% endstep %}

{% step %}

#### 输出完整触发器状态

调用 `PrintDiagnostics()` 从测试脚本中，或按下 **调用** / **Reset** 在 Play Mode 中组件上可见的按钮。该转储会一次显示所有字段，便于轻松发现不匹配之处：

```csharp
trigger.PrintDiagnostics();
```

{% endstep %}

{% step %}

#### 运行 ValidateConfiguration

```csharp
if (!trigger.ValidateConfiguration())
{
    foreach (string warning in trigger.ValidationWarnings)
        Debug.LogWarning($"Trigger validation: {warning}");
}
```

或者启用 **启动时验证** 在 Inspector 中，这样它会在每次 Play 会话开始时自动运行。
{% endstep %}
{% endstepper %}

### TriggerStatus 参考

`ConvaiNarrativeDesignTrigger.CurrentStatus` 始终报告触发器的当前状态。用它来了解触发器为何没有触发。

| Status     | 原因                                    | 解决方案                                                    |
| ---------- | ------------------------------------- | ------------------------------------------------------- |
| `就绪`       | 正常——等待激活条件。                           | 无需操作。                                                   |
| `已触发`      | `仅触发一次` 已启用且触发器已触发。                   | 调用 `ResetTrigger()` 以重新激活它，或禁用 **仅触发一次** 在 Inspector 中。 |
| `排队等待角色就绪` | 触发器已被接受，但角色尚未进入活动会话。                  | 等待会话打开。触发器会自动触发。调用 `CancelQueuedTrigger()` 以中止队列。       |
| `配置错误`     | `ValidateConfiguration()` 检测到一个或多个问题。 | 读取 `验证警告` （请参见以编程方式验证配置）并修复每个问题。                        |
| `已禁用`      | 组件或其父级 GameObject 已被禁用。               | 启用该组件或 GameObject。                                      |

### 常见问题

| 症状                                      | 可能原因                          | 修复                                                                                                                                               |
| --------------------------------------- | ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| 在……之后章节列表为空 **与后端同步**                   | API 密钥缺失或无效                   | 验证你的 API 密钥——请参见 [配置 API 密钥](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/getting-started/configure-api-key.md)；检查 **上一次获取错误** 在 Manager 上 |
| 在……之后章节列表为空 **与后端同步**                   | 未设置角色 ID                      | 设置 **角色 ID** 在 `ConvaiCharacter` 组件                                                                                                              |
| `OnTriggerActivated` 触发了，但章节始终未更改       | 触发器名称与仪表板端不完全匹配（区分大小写）        | 单击 **获取** 在 Trigger 上，从下拉菜单中重新选择正确的触发器                                                                                                           |
| `OnSectionStart` 尽管章节已更改，却始终未触发         | 本地章节 ID 与仪表板不同步               | 单击 **与后端同步** 在 Manager 上；如果仍然有问题，调用 `ClearAllSectionConfigs()` 并重新同步                                                                             |
| `OnPlayerEnterZone` 始终不触发（Collision 模式） | **触发器** 在 Collider 上被禁用       | 启用 **触发器** 在 Collider 组件上                                                                                                                        |
| `OnPlayerEnterZone` 始终不触发（Collision 模式） | 没有 `Rigidbody` 在任一对象上         | 添加一个 `Rigidbody` 到触发器 GameObject 或玩家                                                                                                             |
| `OnPlayerEnterZone` 始终不触发（Collision 模式） | Player GameObject 标签未设置为 `玩家` | 将标签设置为 `玩家` 在 Inspector 中                                                                                                                        |
| 错误的对象激活了触发器                             | **Player 层** 遮罩设置为 `无` (0)    | 设置 **Player 层** 到玩家所在的图层                                                                                                                         |
| 未识别 Player 标签                           | 该标签未在 Unity 的 Tag Manager 中定义 | 在以下位置添加该标签 **Edit > Project Settings > Tags and Layers**                                                                                         |
| “找到多个 ConvaiCharacters” 警告              | `自动查找角色` 无法消除歧义               | 在以下位置显式分配目标角色 **角色** 字段                                                                                                                          |
| 章节显示 **孤立** 徽标                          | 本地同步后，仪表板中的章节被删除              | 如果是有意为之：手动移除条目。若为误删：在仪表板中恢复，然后单击 **与后端同步**                                                                                                       |
| 模板键对角色对话没有影响                            | 键名与仪表板占位符的大小写不匹配              | 精确比较键： `{playerName}` 在仪表板上 → 键 `playerName`，而不是 `PlayerName`                                                                                    |

### 启用诊断

`ConvaiNarrativeDesignTrigger` 具有内置诊断日志记录器。可在 Inspector 中或通过代码启用：

```csharp
trigger.SetDiagnosticsEnabled(true);
```

启用诊断后，每次状态转换——进入/退出区域、队列开始、检测到角色就绪、发送触发器——都会通过以下方式记录到 Console： `ConvaiLogger.Debug`.

如需随时将触发器的完整当前状态输出到 Console：

```csharp
trigger.PrintDiagnostics();
```

`PrintDiagnostics()` 日志：

```
[ConvaiNarrativeDesignTrigger] === DIAGNOSTICS ===
  GameObject: TriggerZone_Checkpoint1
  状态：QueuedWaitingForCharacter
  已触发：False
  仅触发一次：True
  触发器名称：'CheckpointReached'
  触发器 ID：'a1b2c3d4-...'
  激活模式：Collision
  已分配角色：SafetyInstructor
  角色就绪：False
  玩家在区域内：True
  玩家 Transform：PlayerController
  已排队等待就绪：True
  上一次错误：None
  验证警告：0
===========================
```

在 Play Mode 中，Inspector 还会显示一个 **调用** 按钮（触发 `InvokeTrigger()`）以及一个 **Reset** 按钮（触发 `ResetTrigger()`），可直接在 Inspector 中使用，无需编写任何代码。

### 以编程方式验证配置

```csharp
bool valid = trigger.ValidateConfiguration();

如果 !valid
{
    foreach (string warning in trigger.ValidationWarnings)
        Debug.LogWarning($"Trigger validation: {warning}");
}
```

`ValidateConfiguration()` 会执行四项自动检查：

1. **角色引用检查**：验证是否已分配角色并实现 `IConvaiCharacterAgent`.
2. **触发器名称检查**：验证至少有一个 **触发器名称** 或 **触发消息** 非空时。
3. **Collider 检查** （Collision 和 TimeBased 模式）：验证是否存在一个 `Collider` 位于同一个 GameObject 上，并且 **触发器** 被启用时自动发现它。
4. **玩家检测检查**：验证 **Player 标签** 已在 Unity 的 Tag Manager 中定义，并会在以下情况下发出警告： **Player 层** 被设置为 `无` (0).

启用 **启动时验证** 在 Inspector 中启用，以便在以下时间自动运行此检查： `Start()` 这样问题会在 Play Mode 一开始就被捕获。

### 获取失败

如果 `FetchAndSyncFromBackend()` 失败：

1. **上一次获取错误** 在 Manager Inspector 中会显示准确的错误字符串。
2. 调用 `ClearFetchError()` 在解决问题后用于重置错误显示：

```csharp
narrativeManager.ClearFetchError();
```

常见原因：

| 错误                                                  | 原因                                                                                                                   |
| --------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- |
| `“API 密钥未配置。请在 Project Settings > Convai SDK 中设置。”` | 未设置 API 密钥——请参见 [配置 API 密钥](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/getting-started/configure-api-key.md) |
| `“需要 Character ID。”`                                | 在 `ConvaiCharacter`                                                                                                  |
| `“异常：...”`                                          | 网络错误或无法访问 Convai 后端                                                                                                  |
| `“未分配角色或角色没有 ID。”`                                  | Manager 没有角色引用，且自动检测失败                                                                                               |

你还可以检查以下结果： `FetchAndSyncFromBackendAsync()` 在代码中：

```csharp
SectionSyncResult result = await narrativeManager.FetchAndSyncFromBackendAsync();
如果 !result.Success
    Debug.LogError($"Sync failed: {result.Error}");
```

### 待处理状态

当在角色会话打开之前发送模板键或触发器时，SDK 会将它们保存在内部队列中。交付是自动的——你无需手动重新发送任何内容。

| 事件        | 会发生什么                                                              |
| --------- | ------------------------------------------------------------------ |
| 会话打开      | `FlushPending()` 会在内部被调用；所有排队的键和触发器都会按顺序发送。                        |
| 会话断开并重新连接 | `MarkPendingReplayAfterDisconnect()` 会在内部被调用；最新的模板键快照会在下一次连接时重新发送。 |

{% hint style="info" %}
你可以调用 `SetTemplateKey` 或 `InvokeTrigger` 在场景生命周期的任何阶段都可以——包括在 `Awake` 或者在 Play Mode 完全运行之前——一旦连接就绪，SDK 就会正确传递这些值。
{% endhint %}

### 队列超时

`ConvaiNarrativeDesignTrigger`的 **等待就绪后再队列** 功能会每 0.25 秒轮询一次角色就绪状态。超时由以下项控制： **最大等待时间** （默认： `30` 秒）。

当达到超时时， `OnTriggerFailed` 会触发并显示消息：

```
在等待角色就绪 30 秒后超时。
```

若要在超时前取消已排队的触发器：

```csharp
trigger.CancelQueuedTrigger();
```

{% hint style="warning" %}
设置 **最大等待时间** 到 `0` 会完全禁用超时。在某个构建版本中，如果会话始终无法连接（例如因网络中断），等待协程会一直运行，直到场景被卸载。对于生产构建，请始终设置合理的超时时间，并处理 `OnTriggerFailed` 以通知用户或优雅降级。
{% endhint %}

### 控制台日志参考

当以下情况发生时，会出现下列日志消息： **启用诊断** 已开启，或运行时发生错误时。

| 日志消息                                                  | 组件                             | 含义                                                       |
| ----------------------------------------------------- | ------------------------------ | -------------------------------------------------------- |
| `触发器“<name>”已在角色“<character>”上成功调用。`                  | `ConvaiNarrativeDesignTrigger` | 触发器已被接受并成功发送到后端。                                         |
| `触发器“<name>”已排队。正在等待角色就绪（最长 <N> 秒）。`                  | `ConvaiNarrativeDesignTrigger` | 角色会话尚未打开。连接后触发器将自动触发。                                    |
| `角色在 <N> 秒后变为就绪，正在发送已排队的触发器`                          | `ConvaiNarrativeDesignTrigger` | 会话已打开；现在正在发送延迟触发器。仅在以下情况下显示： **启用诊断** 已开启。               |
| `等待角色就绪 <N> 秒后超时。`                                    | `ConvaiNarrativeDesignTrigger` | `MaxWaitTime` 已耗尽。处理 `OnTriggerFailed` 并增加超时时间，或检查会话连接。  |
| `触发器已触发且 TriggerOnce 已启用。调用 ResetTrigger() 以允许它再次触发。` | `ConvaiNarrativeDesignTrigger` | `仅触发一次` 为 `true` 且触发器已经触发。                               |
| `[ConvaiNarrativeDesignTrigger] 验证：<detail>`          | `ConvaiNarrativeDesignTrigger` | 在 Start 时检测到配置问题。请阅读详情字符串以了解具体字段。                        |
| `找到多个 ConvaiCharacters（<N>）。无法自动分配。请显式分配一个。`          | `ConvaiNarrativeDesignTrigger` | 自动查找存在歧义。将正确的角色拖到 **角色** 字段中。                            |
| `章节切换：上一个=<id> → 新的=<id>`                             | `ConvaiNarrativeDesignManager` | 已收到章节切换。如果 `OnSectionStart` 未触发，则章节 ID 不在本地配置列表中——请重新同步。 |
| `同步完成：新增 <N> 个，更新 <N> 个，孤立 <N> 个，重新激活 <N> 个`          | `ConvaiNarrativeDesignManager` | 上一次调用的摘要 **与后端同步** 调用。孤立计数非零表示仪表板中的章节已被删除。               |
| `获取失败：<error>`                                        | `ConvaiNarrativeDesignManager` | API 密钥、角色 ID 或网络问题。检查 **上一次获取错误** 在 Inspector 中。         |

### 触发器未触发

```mermaid
flowchart TD
    A[触发器未触发] --> B[检查 CurrentStatus]
    B --> C{状态？}
    C -- AlreadyFired --> D[调用 ResetTrigger\n或禁用仅触发一次]
    C -- QueuedWaitingForCharacter --> E[等待会话\n或检查 MaxWaitTime]
    C -- ConfigurationError --> F[读取 ValidationWarnings\n修复每个问题]
    C -- Disabled --> G[启用组件\n或其父级 GameObject]
    C -- Ready --> H{角色是否就绪？}
    H -- false --> I{等待就绪后再队列？}
    I -- false --> J[启用等待就绪后再队列\n或在触发前等待会话]
    I -- true --> K[触发器已排队\n等待会话打开]
    H -- true --> L{已设置 TriggerName？}
    L -- empty --> M[获取触发器并选择一个\n或在代码中调用 SetTrigger]
    L -- set --> N[检查网络连接\n和后端图配置]
```

使用 `CurrentStatus` 如需即时诊断，请启用 `EnableDiagnostics` 以跟踪完整事件链，并使用常见问题表来解决最常见的错误配置。

### 下一步

{% content-ref url="/pages/87ddb3e30dd1b009eb7bf39b583b5a654f486dbb" %}
[配置叙事设计触发器](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/features/narrative-design/setting-up-narrative-design-triggers.md)
{% endcontent-ref %}

{% content-ref url="/pages/e2aeb655628e9664d3a8c2993eb219a88fcfeef0" %}
[叙事设计脚本参考](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/features/narrative-design/scripting-narrative-design.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/features/narrative-design/troubleshooting-and-diagnostics.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.
