> 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/character-actions/debugging-and-troubleshooting.md).

# 排查角色动作问题

使用 Convai Troubleshooter、Action Monitor 和症状-修复参考，诊断角色动作设置与运行时问题。

先从 **Convai > 故障排查工具** — 它会检查角色的动作设置，并准确列出需要修复的内容，大多数问题都可一键修复。对于场景运行时的行为，请添加 `ConvaiActionDebugProbe` 到 NPC 的 `GameObject` 并在 Play 模式下观察其计数器更新。要手动测试动作和运行时更新线协议，请打开 **Convai > 操作编辑器** 并切换到其 Live 模式。本页涵盖这三种工具、一个诊断清单，以及常见故障的完整排查表。

### 使用 Convai 故障排查工具检查动作设置

`Convai > 故障排查工具` 会打开 Convai 故障排查工具，这是所有 Convai 模块都会向其报告结果的共享窗口。Actions 是每个角色都具备的模块：即使一个刚刚接线的 `ConvaiCharacter` 即使没有其他模块，也会显示 Actions 行，因为 Actions 适用于每个角色，而不是可选启用的。请先从这里开始，再看下面的运行时工具——大多数动作失败都是设置问题，在你进入 Play 模式之前，故障排查工具就能捕获。

该窗口会加载你当前选中的角色，或者列出场景中每个 `ConvaiCharacter` 场景中的每个 **此场景** 模式。它也可以直接打开，并已聚焦到 Actions 行，可从 Actions Editor 和从 `ConvaiActionConfigSource`的检查器中打开——这两种情况下都是同一个窗口、同一套检查，并不是单独的工具。参见 [验证你的设置](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/getting-started/validate-your-setup.md) 了解故障排查工具如何与整个场景范围的验证器配合。

每条发现都有严重级别——错误、警告、信息或正常——以及标题和消息。可自动修复的发现会显示修复按钮；关于已编写内容（而不是场景对象）的发现会显示一个 **打开** 按钮，可跳转到 Actions Editor 中对应的具体动作。使用 **重新检查** 在做出更改后，或使用 **修复所有可修复项** 一次应用所有一键修复。

常见发现：

| 标题               | Message                                                            | 含义                                                              |
| ---------------- | ------------------------------------------------------------------ | --------------------------------------------------------------- |
| 已启用 Actions      | `此角色目前还不能持有任何动作。`                                                  | 没有 `ConvaiActionConfigSource` 在角色上——添加一个，或让修复按钮自动添加。            |
| 运行 Actions       | `尚未设置任何内容来运行动作，因此此角色永远不会执行任何被要求的操作。`                               | 没有 `ConvaiActionDispatcher` 在角色上（且该角色并未在自定义代码中声明正在运行动作）。        |
| 已编写 Actions      | `目前还未设置任何动作。打开 Convai > Actions Editor，使用“+ Add Action”编写你的第一个动作。` | `ConvaiActionConfigSource` 还没有动作定义。这只是信息提示，不是错误——角色会说话，但不会执行动作。 |
| 动作行为 — “\<name>” | `尚未为此动作选择行为，而且也没有任何内容会自动推荐。直到你在 Actions Editor 中选择一个之前，这个动作都不会运行。` | 该动作定义没有绑定执行器。请在 Actions Editor 中打开该动作并选择一个行为。                   |
| 动作行为 — “\<name>” | `该动作已设置为使用 <behavior>，但此角色尚未拥有它。`                                  | 该动作指定了一个真实的执行器类型，但角色没有该组件。使用修复按钮添加它。                            |

这不是完整的发现集——故障排查工具还会报告目标链接、行为宿主、动作反馈以及所需的同级或目标组件。参见 [故障排除](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/troubleshooting.md) 了解整个 SDK 的故障排查中心，其中包括 Actions 之外的故障类别。

### ConvaiActionDebugProbe（动作监视器）

`MonoBehaviour` — `Convai.Runtime.Actions`

菜单路径： `添加组件 → Convai → Actions → Diagnostics → Convai Action Monitor`

限制： `DisallowMultipleComponent`, `RequireComponent(ConvaiCharacter)`

该探针会自动解析 `ConvaiCharacter` 和 `ConvaiActionDispatcher` 来自同一个 `GameObject`。其检查器标题为 **动作监视器**：在 Edit 模式下会显示进入 Play 模式的提示；在 Play 模式下会显示一个 **活动** 部分，只列出至少触发过一次的事件类别，每项显示为 `#<count> <category>` 下方显示最近一次的详细文本，以及 **清除** 和 **复制** 按钮。

#### 检查器字段

| 字段                      | 类型                       | 说明                                            |
| ----------------------- | ------------------------ | --------------------------------------------- |
| `_character`            | `ConvaiCharacter`        | 自动解析。跟踪来自 Convai 的原始动作批次。                     |
| `_dispatcher`           | `ConvaiActionDispatcher` | 自动解析。跟踪执行生命周期事件。                              |
| `_logToConsole`         | `bool`                   | 启用后，每个记录的事件也会打印到控制台。若想减少测试时的输出，请禁用。           |
| `_receivedBatchCount`   | `int`                    | 通过以下方式从 Convai 接收到的批次数总计 `OnActionsReceived`. |
| `_startedStepCount`     | `int`                    | 调度器已开始执行的步骤总数。                                |
| `_succeededStepCount`   | `int`                    | 返回的步骤总数 `成功`.                                 |
| `_failedStepCount`      | `int`                    | 返回的步骤总数 `Failed`.                             |
| `_unhandledStepCount`   | `int`                    | 返回的步骤总数 `未处理`.                                |
| `_completedStepCount`   | `int`                    | 已完成的步骤总数，无论成功与否——会与上方某个计数器一起触发。               |
| `_abortedBatchCount`    | `int`                    | 被以下原因中断的批次数总计 `StopBatch` 失败策略。               |
| `_lastReceivedBatch`    | `string`                 | 最近接收的批次的 JSON。                                |
| `_lastStepStarted`      | `string`                 | 最近开始的步骤摘要。                                    |
| `_lastStepSucceeded`    | `string`                 | 最近成功的步骤摘要。                                    |
| `_lastUnhandledStep`    | `string`                 | 最近未处理的步骤摘要。                                   |
| `_lastFailedStepDetail` | `string`                 | 最近失败的步骤摘要。                                    |
| `_lastStepCompleted`    | `string`                 | 最近完成的步骤摘要，无论结果如何。                             |
| `_lastFailureReason`    | `string`                 | 最近完成的步骤报告中的失败消息（如果失败）。                        |

该探针只保留每个事件类别最近一次出现的记录以及一个累计计数——它是按类别划分的“最新已知状态”视图，而不是时间顺序日志。要从代码中注入测试批次或重置探针，请调用其公开的 `InjectTestBatch()` 或 `ResetProbeState()` 方法；要交互式注入，请使用下文介绍的 Actions Editor 的 Live 模式。

#### 控制台日志格式

当 `_logToConsole` 启用时，探针会按以下格式写入控制台：

```
[ConvaiActionDebugProbe] 已接收动作批次 #1: [{"name":"Move To","target":"Extinguisher"}]
[ConvaiActionDebugProbe] 调度器批次已开始。
[ConvaiActionDebugProbe] 步骤已开始 #1: cmd='Move To Extinguisher', def='Move To', target=Object:Extinguisher
[ConvaiActionDebugProbe] 步骤成功 #1: cmd='Move To Extinguisher', def='Move To', target=Object:Extinguisher
[ConvaiActionDebugProbe] 调度器批次已完成。
```

对于失败情况：

```
[ConvaiActionDebugProbe] 步骤失败 #1: cmd='Move To Cupboard', def='<unresolved>', target=None:<none>
[ConvaiActionDebugProbe] 调度器批次已中止 #1。
```

### 从 Actions Editor 测试动作

`EditorWindow` — `Convai.Editor.Actions`

菜单路径： `Convai → 动作编辑器`

Actions Editor 的 Live 模式用于注入命令、测试目标解析以及构建运行时动作配置补丁。切换到 Live 模式，选择一个角色，并打开 **高级** 组即可看到三个卡片：

**发送原始命令** 会直接向调度器发送一条动作命令，完全绕过对话——与 Convai 真实命令走的是同一分发路径，因此时序、策略和事件表现完全一致。输入一个 **动作名称** 以及可选的 **目标 / 参数**，然后选择 **发送**，或者选择 **发送到第一个已知对象** 使其指向角色 Known Objects 列表中的第一项。每个已编写的动作也都有自己的单击按钮。如果项目注册了 `IConvaiActionDebugPresetProvider`，其模板和命名注入预设也会显示在这里。

**测试目标解析** 会检查一段文本会解析到哪个目标，而不会发送动作——在 **目标文本** 中输入并选择 **解析**。将控制台打开到 Debug 详细级别，可查看是哪个匹配步骤（精确名称、别名、规范化文本、部分匹配或最近匹配）找到结果。

**运行时会话状态与补丁编写器** 仅在 Play 模式下、角色连接后可用。在 Play 模式之外，它会提示你进入 Play 模式。运行后，它会显示 Convai 已为该角色确认的动作、对象、角色和注意对象，以及每个待处理运行时更新及其确认状态。其下方的编写器会构建一个 `ConvaiActionConfigPatch`: **加载已确认内容** 将角色当前已确认的配置加载到草稿中，并勾选所有字段， **重置草稿** 将其清空， **预览** 在本地验证草稿而不发送任何内容，并且 **发送补丁** 发送它——仅在角色已连接且至少包含一个字段时才可用。参见 [在运行时更新角色动作](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/features/character-actions/update-actions-at-runtime.md) 了解完整的确认模型。

运行时动作状态由后端确认：更新会一直保持待处理，直到 Convai 返回确认；成功的确认会按发送顺序提交。错误状态、格式错误或不匹配的确认元数据，或 30 秒超时，都会丢弃待处理的变更且不重试，控制台会记录 `Runtime action mutation discarded update_id=<id> reason=<reasonCode>` (`ConvaiCharacter.DynamicContext.cs:669`）。断开连接也会丢弃任何待处理变更且不重试，但会静默处理——不会记录此消息。若确认中的 action-generation-strategy 状态为 `requires_reconnect`，控制台还会记录 `运行时动作更新 ACK 需要重新连接；未执行自动重连（update_id=<id>)` (`ConvaiCharacter.DynamicContext.cs:628`）——SDK 会暴露此状态，但不会自动重新连接。

### 诊断清单

当动作未执行时，请按顺序使用此清单：

{% stepper %}
{% step %}

#### 先检查 Convai 故障排查工具

打开 **Convai > 故障排查工具** 在选中角色的情况下。如果它报告 Actions 错误，请先修复再继续——此清单中剩余的大多数步骤，故障排查工具已经在替你检查了。
{% endstep %}

{% step %}

#### 验证 Convai 是否正在发送动作

检查 `_receivedBatchCount` 在 Play 模式下说出命令后，查看探针检查器的 Activity 部分。

* **计数器递增** → Convai 返回了一个动作批次；继续下一步。
* **计数器保持为 0** → Convai 没有返回动作响应。可能原因：
  * `ConvaiActionConfigSource` 没有动作定义（Convai 不知道可用动作）
  * 该角色未配置为针对此角色 ID 返回动作
  * 会话未成功连接
    {% endstep %}

{% step %}

#### 验证调度器是否正在处理批次

如果 `_receivedBatchCount` 递增但 `_startedStepCount` 仍为 0：

* `ConvaiActionDispatcher` 可能缺失或在 NPC 的 `GameObject`
* 检查调度器是否位于 **同一个 `GameObject`** current `ConvaiCharacter`
* 验证检查器中调度器组件已启用（组件名称旁的复选框）
  {% endstep %}

{% step %}

#### 阅读步骤失败消息

如果 `_failedStepCount` 递增，请检查 Activity 部分的 **步骤失败** 行，或查看控制台中的失败消息。调度器会记录确切原因：

| 控制台消息                                      | 原因                          |
| ------------------------------------------ | --------------------------- |
| `未找到动作“X”的本地动作定义。`                         | 动作名称不匹配——见下一步               |
| `动作“X”没有绑定任何动作行为。`                         | Executor 字段为空——分配执行器组件      |
| `动作“X”的目标“Y”需要 <Requirement>，但解析为 <Kind>。` | Convai 发送了一个不匹配任何已注册对象的目标名称 |
| {% endstep %}                              |                             |

{% step %}

#### 检查动作名称是否不匹配

动作名称匹配 **不区分大小写** 但 **空格是有意义的**. `移动到` 和 `移动到` 匹配。 `移动到` 和 `MoveTo` 不匹配。

在 `_lastReceivedBatch`，找出 Convai 发送的确切名称。将其与 `ActionName` 中的字段 `ConvaiActionConfigSource`。它们必须逐字符完全一致（忽略大小写）。
{% endstep %}

{% step %}

#### 验证组件引用

在 `ConvaiActionConfigSource`，展开每个 **动作定义** 条目：

* **Executor 字段为空** → 步骤失败并提示“没有绑定任何动作行为。”请将执行器组件引用拖入 Executor 字段。
* **执行器未实现 `IConvaiActionExecutor`** → 步骤失败。自定义执行器必须实现该接口。
  {% endstep %}

{% step %}

#### 使用原始命令测试

打开 **Convai → 动作编辑器**，切换到 **实时** 模式，打开 **高级**，并使用 **发送原始命令** （或选择已编写动作的一键按钮）。这会直接向调度器提交命令，绕过 Convai。

* **步骤成功** → 流水线工作正常；问题在于 Convai 返回动作的方式，而不是你的 Unity 设置。
* **步骤失败** → 问题出在本地组件配置（执行器、NavMesh、缺失引用）。

选择 **清除** 在测试运行之间清空 Action Monitor，以保持其 Activity 部分易读。
{% endstep %}
{% endstepper %}

### 故障排查表

| 症状                                                                | 可能原因                                               | 修复方法                                                                                                     | 验证                                                     |
| ----------------------------------------------------------------- | -------------------------------------------------- | -------------------------------------------------------------------------------------------------------- | ------------------------------------------------------ |
| Convai 故障排查工具报告 `此角色目前还不能持有任何动作。`                                 | 没有 `ConvaiActionConfigSource` 在角色上                 | 使用该发现的修复按钮，或手动添加 `ConvaiActionConfigSource` 到角色                                                          | 在故障排查工具中重新检查；Actions Enabled 行会变为 `此角色已启用 Actions。`    |
| Convai 故障排查工具报告 `尚未设置任何内容来运行动作，因此此角色永远不会执行任何被要求的操作。`              | 没有 `ConvaiActionDispatcher` 在角色上                   | 使用该发现的修复按钮，或手动添加 `ConvaiActionDispatcher` 到同一个 `GameObject`                                              | 在故障排查工具中重新检查；Running Actions 行会变为 `此角色已设置为运行动作。`       |
| `_receivedBatchCount` 说话后仍保持 0                                    | `ConvaiActionConfigSource` 缺失或没有动作定义               | 添加 `ConvaiActionConfigSource` 至少包含一个动作定义；只有在 Convai 知道已配置动作时才会返回动作                                       | 再说一遍； `_receivedBatchCount` 递增                         |
| `_receivedBatchCount` 递增但 `_startedStepCount` 仍为 0                | `ConvaiActionDispatcher` 缺失、已禁用或位于错误的 `GameObject` | 将调度器添加到同一个 `GameObject` current `ConvaiCharacter`；验证其已启用                                                 | `_startedStepCount` 在下一批次中递增                           |
| `_failedStepCount` 递增： `未找到动作“X”的本地动作定义。`                         | Convai 发送的动作名称与任何 `ActionName` 本地定义中的              | 打开 `_lastReceivedBatch` 以查看确切名称；在 `ConvaiActionConfigSource`                                             | 下一次匹配的批次会递增 `_startedStepCount` 而不是 `_failedStepCount` |
| `_failedStepCount` 递增： `动作“X”没有绑定任何动作行为。`                         | `执行器` 中的字段 `ConvaiActionDefinition` 为空             | 将执行器组件引用拖入 `执行器` 中的字段 `ConvaiActionConfigSource`，或使用 Convai 故障排查工具的“Action Behavior”修复按钮                 | 步骤到达 `_startedStepCount` 并且执行器的行为运行                    |
| 一个 `ConvaiUnityEventActionExecutor` 动作从未触发其监听器                    | 执行器的 `UnityEvent` 在检查器中没有连接持久监听器                   | 在执行器的 `UnityEvent` 字段上连接一个监听器；Convai 的 MCP 动作诊断工具将其标记为 `ACTION_EVENT_UNWIRED`                            | 已连接的监听器会在下次动作执行时运行                                     |
| `_failedStepCount` 递增： `动作“X”的目标“Y”需要 <Requirement>，但解析为 <Kind>。` | Convai 的目标名称与任何已注册对象或角色都不匹配                        | 打开 `_lastReceivedBatch` 以查看目标名称；验证它是否匹配 `名称` 中的一条 **可操作对象** 或 **可操作角色** （不区分大小写）                         | 步骤解析目标并 `_startedStepCount` 递增                         |
| `_unhandledStepCount` 递增                                          | 执行器返回 `未处理` — 执行器拒绝处理此调用                           | 检查执行器逻辑； `未处理` 表示执行器选择不运行，并不意味着出了问题                                                                      | 执行器返回 `成功`, `已应答`，或 `Failed` ，在逻辑修正后再说                 |
| `_abortedBatchCount` 递增                                           | 某一步失败且 `StopBatch` 策略中止了剩余步骤                       | 修复失败的步骤（见上文），或更改 `FailurePolicy` 为 `继续批次` 如果步骤彼此独立                                                       | `OnBatchCompleted` 触发，而不是 `OnBatchAborted` 在下一批次中      |
| NPC 传送而不是导航移动                                                     | 正在使用基于 Transform 的自定义移动执行器                         | 使用 `ConvaiNavMeshLocomotion`驱动的移动，或尊重你的移动系统的自定义执行器                                                       | NPC 会平滑移动到目标，而不是直接瞬移过去                                 |
| NPC 开始移动然后冻结                                                      | 移动执行器的 `NavMeshAgent` 卡住了，或者其路径被阻塞了                | 烘焙 NavMesh（**窗口 → AI → Navigation → Bake**）；验证 NPC 和目标都位于 NavMesh 表面；将 `TimeoutSeconds` 在动作定义上设置，以防止无限阻塞 | NPC 能到达目标并完成步骤，而不是超时                                   |
| 在检查器中配置了 Actions，但场景切换后不工作                                        | 连接时发送的配置现在已过期                                      | 结束会话并重新连接；动作配置只会在连接时发送一次                                                                                 | 重新连接后请求的动作将应用新的配置                                      |
| 动作在编辑器中可用，但在构建中不可用                                                | 构建中未包含执行器组件                                        | 验证执行器脚本是否在项目的编译范围内；检查是否有 `[assembly: ...]` 排除项                                                           | 构建中的控制台显示相同的 `ConvaiActionDebugProbe` 输出与编辑器一致         |
| `DynamicContext.SetCurrentAttentionObject` 调用没有效果                 | 不在活动会话中，或对象名称不在活动配置中                               | 仅在之后调用 `ConnectAsync` 完成；对象名称必须与 `ConvaiActionConfigSource.Objects`                                      | 后续的动作目标解析会反映新的注意对象                                     |
| Actions Editor 中待处理的运行时更新从未清除                                     | 该更新已被丢弃——ACK 错误、格式错误/不匹配的元数据，或 30 秒超时（或在断开连接时静默丢弃） | 检查控制台中的 `运行时动作变更已丢弃 update_id=... reason=...`；已丢弃的更新不会重试，请使用新的 update ID 重新发送                            | 待处理条目消失，最后一次确认显示新的状态                                   |
| Actions Editor 的最后一次动作更新确认显示 `requires_reconnect`                 | Convai 已应用更改，但 action-generation-strategy 需要新的会话   | 结束会话并重新连接；SDK 不会自动重连                                                                                     | 重新连接后，最后一次确认会反映重新应用的状态                                 |
| **发送补丁** 在运行时补丁编写器中保持禁用                                           | 角色未连接，或草稿中未包含任何字段                                  | 在会话连接后发送；发送前至少勾选一个字段                                                                                     | 一旦连接并包含至少一个字段，按钮就会启用                                   |

### 下一步

{% content-ref url="/pages/4001c6ae3c6d4603942748007a37a67812bb7e9a" %}
[在运行时更新角色动作](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/features/character-actions/update-actions-at-runtime.md)
{% endcontent-ref %}

{% content-ref url="/pages/0341126fa4c492311dab4fb6aca6d0c64191016b" %}
[角色动作脚本参考](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/features/character-actions/actions-scripting-reference.md)
{% endcontent-ref %}

{% content-ref url="/pages/21a0b0c11649e9125ef5195167e66c3a2caaadf1" %}
[验证你的设置](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/getting-started/validate-your-setup.md)
{% endcontent-ref %}

{% content-ref url="/pages/aed151614a7019028126be07590213a17602a2f2" %}
[故障排查](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/troubleshooting.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/features/character-actions/debugging-and-troubleshooting.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.
