> 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-unreal-engine-plugin/features/character-actions/how-character-actions-work.md).

# 角色动作的工作原理

了解 Convai 角色动作如何从会话设置进入排队的 Blueprint 处理器执行，并完成报告。

角色动作将 Convai 所说的内容与角色在关卡中的行为关联起来。当玩家发言时，Convai 可以同时返回一个口语回复和一系列命名动作——移动到某个位置、跟随玩家、与对象交互。插件会将这些动作分发到 NPC Actor 上匹配的 Blueprint 处理事件中，并按顺序逐个执行。

### 所需设置

| 组件 / 资源                        | 适用于               | 备注                                                  |
| ------------------------------ | ----------------- | --------------------------------------------------- |
| `Convai 聊天机器人` 组件              | 所有动作              | 携带 `Environment` 属性（动作模板、对象、角色）以及 `ActionsQueue`.   |
| `Convai Player` 组件             | 所有动作              | 在玩家 Pawn 上用于语音输入所必需。                                |
| Blueprint 处理函数                 | 每个应执行的动作          | 每个动作名称对应一个函数，接收 `FConvaiResultAction`.              |
| NPC Actor 上的 AI Controller     | 移动动作（`移动到`, `跟随`) | 适用于 `AI Move To` 才能工作。使用 Unreal 内置的 `AIController`. |
| `Nav Mesh Bounds Volume` （已构建） | 移动动作              | 必须覆盖 NPC 生成点和所有导航目标。关卡更改后请重新构建。                     |

对于非移动动作（自定义行为、动画、状态更改），只需要 chatbot 组件和 Blueprint 处理函数。

### 关键概念

有六个概念构成了系统的工作方式。下面每个部分会详细介绍一个，但先快速看一下整体：

| 概念         | 含义                                                                    |
| ---------- | --------------------------------------------------------------------- |
| **动作契约**   | 在会话开始前发送给 Convai 的动作、对象和角色列表——定义角色被允许执行和引用的内容。                        |
| **动作流水线**  | 两条并行通道：一条播放语音音频，另一条按顺序存储并执行一系列动作。                                     |
| **队列与分发**  | 插件维护一个待处理动作队列。每当某个处理程序报告完成时，队列就前进一项，接着运行下一个处理程序。                      |
| **完成模型**   | 每个处理程序都必须调用 `HandleActionCompletion` ，在其完成时。不调用该函数，队列就会停滞，后续动作永远不会执行。 |
| **等待语音门控** | 一个可选的按动作配置标志，用于延迟动作触发，直到角色开始或结束说话，从而让移动和语音保持同步。                       |
| **运行时变更**  | 会话进行期间可以添加或移除对象和角色；本地环境会立即更新。                                         |

### 动作契约

在会话开始前，聊天机器人组件会读取 `Environment` 属性——其动作模板、已注册对象和角色列表——并将这些信息发送给 Convai。Convai 会据此知道角色可以执行哪些动作，以及在根据玩家语音选择动作时可以引用哪些对象。

该契约包含三部分：

* **动作** —— 一个有序列表，包含 `FConvaiAction` 模板，每个模板都有名称、可选描述以及可选的类型参数。该列表定义在 `Environment` 的属性中 `UConvaiChatbotComponent`，位于 `动作` 字段。
* **对象** —— 一个数组，包含 `FConvaiObjectEntry` 描述场景中可交互对象的值。每个条目都有一个 `名称`，可选的 `说明`，以及导航目标字段。
* **角色** —— 一个数组，包含 `FConvaiObjectEntry` 描述场景中其他角色的值。

该 **启用动作** 位于 `Convai 聊天机器人` 组件的 `Environment` 属性充当主开关。其默认值为 `true` 在每个新组件上均为开启，因此该功能开箱即用。禁用后，会话开始时不会发送契约，角色将仅作为纯对话型 NPC。

{% hint style="info" %}
会话开始时，动作集即固定。通过 `AddAction` / `RemoveAction` 添加或移除动作只会影响下一次会话——当前进行中的会话会保留其连接时所使用的动作集。
{% endhint %}

### 动作流水线

当玩家与 Convai 角色对话时，插件会通过两条并行通道处理响应：

1. **语音通道** —— 音频流会传送到角色的音频组件进行播放。聊天机器人会触发 `On Actions Received` 和 `OnStartedTalking` / `OnFinishedTalking` 事件，随着语音进程发生。
2. **动作通道** —— Convai 会根据 `action_config` 契约解析响应并返回一系列 `FConvaiResultAction` 结构体。插件会将该序列存储到 `ActionsQueue` 在 `UConvaiChatbotComponent`.

两条通道彼此独立。语音播放的同时，动作队列会执行。

### 队列与分发

插件维护一个 `FConvaiResultAction` 中的条目队列 `ActionsQueue`。当新的动作序列到达时，插件会：

1. 如果队列中已包含一个正在进行的动作，则保留该首个动作，并用传入序列替换其余排队动作。如果队列为空，则按原样存储传入序列。
2. 调用 `StartFirstAction`，它会从队列中读取第一项并调用 `TriggerNamedBlueprintAction`.
3. `TriggerNamedBlueprintAction` 会查找一个名称与 `操作` 结果的字段匹配的 Blueprint 函数或事件。它会先检查所属 Actor，然后检查聊天机器人组件。处理程序可以接收一个 `FConvaiResultAction` 参数，或者不接收参数。

分发器基于名称。Unreal 对处理程序名称的解析不区分大小写，但空格和标点仍必须匹配。如果在任一目标上都找不到匹配函数，插件会记录警告，不会调用处理程序，并且队列会停滞，直到 `HandleActionCompletion` 或 `AbortActionSequence` 被调用。

### 取消动作计划

角色在某个动作仍在运行时可以改变路线——玩家重新指引它，或者新情况使当前计划变得毫无意义。 `CancelCurrentActionPlan` 在 `UConvaiChatbotComponent` (Blueprint 显示名称 **Cancel Current Action Plan**）会以协作方式取消，而不是在运行中的处理程序下方直接抽走队列：已排队的动作会立即丢弃，但会向当前活动的处理程序提供一个可选的 Blueprint 事件，名称正好为 `Cancel <Action Name>`，并携带原始的 `FConvaiResultAction`，以便在替代计划开始之前，能干净地停止其计时器、委托或延迟任务。重复调用只会请求一次取消，并等待一次终止性确认。

实现了可选取消事件的处理程序必须调用 `HandleActionCancellation` ，在其完全静止后——即在计时器、委托、任务和回调全部停止之后。该调用不会报告成功或失败，而是释放所持有的替代计划，以便队列继续前进。未实现取消事件的处理程序将由其自行完成；无论哪种情况，自定义取消处理程序都必须且只能调用一个终止 API—— `HandleActionCancellation` 或其现有的完成路径——绝不能两者都用。

启用 `bEnableCancelActionPlanAction` (Blueprint 显示名称 **启用取消动作计划**，类别 `Convai|Actions|Experimental`）在聊天机器人组件上会添加一个保留的 `取消动作计划` 控制动作到发送给 Convai 的契约中，因此角色本身可以在玩家改道或放弃其正在做的事情时决定发起取消。参见 [配置动作](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unreal-engine-plugin/features/character-actions/configuring-actions.md#experimental-built-in-actions) 了解该开关，以及 [Actions Blueprint 参考](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unreal-engine-plugin/features/character-actions/actions-blueprint-reference.md) 了解完整的函数和事件列表。

### 等待语音门控

`FConvaiAction` 具有一个 `bWaitForBotSpeech` 标志。若在某个动作模板上设置此标志，且该动作作为新接收序列的首个动作到达（即序列到达时队列为空），插件会延迟启动该动作，直到 Convai 开始说话（`OnStartedTalking`）或说完话（`OnFinishedTalking`），以先触发者为准。每个角色的超时（`ActionWaitForBotSpeechTimeoutSec`，默认 `2.0` 秒，不向 Blueprint 暴露）会在两个语音事件都未及时到达时仍然触发该动作。

一个可选的 `DelayAfterBotSpeechSec` 字段会在语音条件满足后再额外增加延迟。

### 完成模型

处理程序负责报告结果。处理程序完成其工作后，必须调用 `HandleActionCompletion` 在 `UConvaiChatbotComponent`:

* `IsSuccessful = true` —— 插件会出队当前动作并启动下一个。
* `IsSuccessful = false` —— 插件会清空剩余队列。角色不会尝试下一个动作。

当 `bAutoReport` 是 `true` （默认值）时，插件还会向 Convai 发送一个描述结果的上下文事件。Convai 在生成角色下一次口语回复时会使用此信息。

如果处理程序遇到无法恢复的错误，并希望 Convai 生成一个全新的动作计划，则调用 `AbortActionSequence` 来替代，且可选地传入一段文本来描述哪里出了问题。

下图展示了一个从开始到完成的单动作交换流程。若序列包含多个动作，则每次 `HandleActionCompletion(true)` 调用都会让队列前进一步。

```mermaid
sequenceDiagram
    participant Player
    participant Convai
    participant Plugin
    participant Handler

    Player->>Convai: 语音输入
    Convai-->>Plugin: 语音音频 + 动作序列
    Plugin->>Plugin: 更新 ActionsQueue
    Plugin->>Handler: TriggerNamedBlueprintAction(Action, ResultAction)
    Handler->>Handler: 执行行为
    Handler->>Plugin: HandleActionCompletion(IsSuccessful)
    Plugin->>Plugin: 出队并启动下一个动作
    Plugin->>Convai: 上下文事件（结果）
```

### 运行时环境变更

可以在运行时使用 `添加对象`, `RemoveObject`, `AddCharacter`，以及 `RemoveCharacter` 上的一组方法对本地环境中的对象和角色进行添加或移除。 `UConvaiChatbotComponent`本地 `EnvironmentData` 镜像会立即更改，并且插件在解析后续动作结果时会使用它。

运行时变更不会改变动作集本身；动作集在下一次重新连接之前都是固定的。对于实时会话，场景上下文更新会通过 `update-scene-metadata` 发送，前提是被更改的条目尚未包含在连接时的场景元数据快照中。

### 下一步

{% content-ref url="/pages/9d759a9e65c274645e91b88390d8bb2c4762bd80" %}
[配置动作](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unreal-engine-plugin/features/character-actions/configuring-actions.md)
{% endcontent-ref %}

{% content-ref url="/pages/d1aaea82f339a27b3ce67918aa343caebba0762c" %}
[内置动作处理器](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unreal-engine-plugin/features/character-actions/built-in-action-handlers.md)
{% endcontent-ref %}

{% content-ref url="/pages/4034933484ffa13478584311631f11ea8d503bb4" %}
[构建自定义动作处理器](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unreal-engine-plugin/features/character-actions/building-custom-action-handlers.md)
{% endcontent-ref %}

{% content-ref url="/pages/8e18d509947b40274dca96b384f432486348198f" %}
[动作 Blueprint 参考](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unreal-engine-plugin/features/character-actions/actions-blueprint-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-unreal-engine-plugin/features/character-actions/how-character-actions-work.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.
