> 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 > Troubleshooter** — 它会检查角色的动作设置，并精确列出需要修复的内容，其中大多数问题可一键修复。若要在场景运行时查看行为，请添加 `ConvaiActionDebugProbe` 到 NPC 的 `游戏对象` ，并在 Play 模式下观察其计数器更新。要手动测试动作和运行时更新线协议，请打开 **Convai > Actions Editor** 并切换到其 Live 模式。本页涵盖全部三种工具、诊断清单以及常见故障的完整排障表。

### 使用 Convai Troubleshooter 检查动作设置

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

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

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

常见发现：

| 标题               | 消息                                                                    | 含义                                                              |
| ---------------- | --------------------------------------------------------------------- | --------------------------------------------------------------- |
| 已启用 Actions      | `此角色还无法承载任何动作。`                                                       | 否 `ConvaiActionConfigSource` 在角色上——添加一个，或者让修复按钮自动添加。            |
| 运行 Actions       | `没有任何用于运行动作的设置，所以这个角色永远不会执行它被要求做的事。`                                  | 否 `ConvaiActionDispatcher` 在角色上（并且该角色没有被自定义代码声明为正在运行动作）。        |
| 已编写 Actions      | `目前还没有设置任何动作。打开 Convai > Actions Editor，并使用“+ Add Action”来编写你的第一个动作。` | `ConvaiActionConfigSource` 还没有任何动作定义。这只是信息提示，不是错误——角色会说话，但不会行动。 |
| 动作行为 — '\<name>' | `此动作还未选择任何行为，也没有任何内容会自动建议。直到你在 Actions Editor 中为其选择一个，它才会运行。`         | 该动作定义没有绑定执行器。请在 Actions Editor 中打开该动作并选择一个行为。                   |
| 动作行为 — '\<name>' | `此动作被设置为使用 <behavior>，但此角色还没有它。`                                      | 该动作命名了一个真实的执行器类型，但角色没有该组件。使用修复按钮添加它。                            |

这还不是完整的发现集合——Troubleshooter 还会报告目标链接、行为宿主、动作反馈以及所需的同级或目标组件。参见 [故障排查](/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` 来自同一个 `游戏对象`。其 Inspector 标题为 **Action Monitor**：在 Edit 模式下会提示你进入 Play 模式；在 Play 模式下会显示一个 **活动** 部分，只列出至少触发过一次的事件类别，每个都显示为 `#<count> <category>` ，其下方显示最近一次的详细文本，并带有 **清除** 和 **复制** 按钮。

#### Inspector 字段

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

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

#### 控制台日志格式

当 `_logToConsole` 已启用时，探针会以这些格式写入 Console：

```
[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`

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

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

**测试目标解析** 会检查一段文本会解析到哪个目标，而不会发送动作——输入到 **目标文本** 并选择 **Resolve**。打开 Console 并将日志详细级别设为 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 秒超时，会丢弃待处理的变更，且不会重试；Console 会记录 `运行时动作变更已丢弃 update_id=<id> reason=<reasonCode>` (`ConvaiCharacter.DynamicContext.cs:669`）。断开连接也会丢弃任何待处理的变更且不会重试，但会静默处理——不会记录此消息。如果确认中的 action-generation-strategy 状态为 `requires_reconnect`，Console 还会记录 `运行时动作更新 ACK 需要重新连接；未执行自动重连（update_id=<id>）` (`ConvaiCharacter.DynamicContext.cs:628`）——SDK 会暴露此状态，但不会自动重连。

### 诊断清单

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

{% stepper %}
{% step %}

#### 先检查 Convai Troubleshooter

打开 **Convai > Troubleshooter** ，并选中角色。如果它报告了 Actions 错误，请先修复它再继续——此清单后面大部分步骤其实都是 Troubleshooter 已经在帮你检查的内容。
{% endstep %}

{% step %}

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

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

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

{% step %}

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

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

* `ConvaiActionDispatcher` 可能缺失，或在 NPC 的上被禁用 `游戏对象`
* 检查调度器是否位于 **同一个 `游戏对象`** 为 `ConvaiCharacter`
* 在 Inspector 中验证调度器组件已启用（组件名称旁的复选框）
  {% endstep %}

{% step %}

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

如果 `_failedStepCount` 增加时，请查看 Activity 部分的 **步骤失败** 行，或者在 Console 中查看失败消息。调度器会记录确切原因：

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

{% step %}

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

动作名称匹配时 **不区分大小写** ，但 **空格是有区别的**. `Move To` 和 `move to` 可匹配。 `Move To` 和 `MoveTo` 不可匹配。

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

{% step %}

#### 验证组件引用

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

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

{% step %}

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

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

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

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

### 故障排查表

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

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
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=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
