> 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/building-custom-action-handlers.md).

# 构建自定义动作处理器

自定义动作处理器是 NPC Actor 上的 Blueprint 函数或事件，插件会在队列中收到匹配的动作名称时调用它们。在聊天机器人中声明该动作，在角色 Blueprint 中搭建一个处理器，运行你的逻辑，然后调用 `处理动作完成` 以便队列可以继续前进。

### 先决条件

* 角色动作已在聊天机器人中启用。参见 [角色动作快速开始](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unreal-engine-plugin/features/character-actions/character-actions-quick-start.md).
* 你知道要添加的动作名称与处理器名称完全匹配，包括空格。

### 声明动作模板

{% stepper %}
{% step %}

#### 向 Actions 数组添加一项

选择 NPC Actor。在 **Convai | Actions > Environment > Actions**，点击 **+**.

将 **名称** 到一个唯一的动词短语，例如 `"Print"`。将 **描述** 设置为给 Convai 的一个简短提示，例如 `"Print a debug message to the screen"`。将 **参数** 留空，以表示无参数动作。
{% endstep %}

{% step %}

#### 编译 Blueprint

点击 **编译** 角色 Blueprint，以便在连接处理器之前保存新动作模板。
{% endstep %}
{% endstepper %}

{% hint style="info" %}
保持动作名称和描述简短。过长的描述会增加发送给 Convai 的上下文，但不会改善行为。将 **描述** 留空，当动作名称已经不言自明时。
{% endhint %}

### 使用 Create Convai Action Handler 搭建处理器

该 `ConvaiEditor` 模块会添加一个 **Create Convai Action Handler** 条目到 Blueprint 图表的上下文菜单中。使用它来生成一个名称正确且参数类型合适的处理器。

{% stepper %}
{% step %}

#### 打开角色 Blueprint 的 Event Graph

打开拥有该功能的 NPC Actor Blueprint `Convai Chatbot` 组件上。
{% endstep %}

{% step %}

#### 创建处理器

在 **事件图表** 并搜索 **Create Convai Action Handler**.

选择你添加的动作（例如 `Print`），选择 **事件（在 Event Graph 上）** 或 **函数（新函数图表）**，并确认创建。该工具会添加一个名称与动作完全相同的处理器，并带有一个 `FConvaiResultAction` 输入，并在末尾连接一个 `处理动作完成` 调用。
{% endstep %}

{% step %}

#### 在事件和完成之间添加处理器逻辑

将你的行为连接在事件引脚和 `处理动作完成`。对于一个 `Print` 动作，添加一个 **打印字符串** 节点，并使用类似以下的字面消息： `"This is the print action"`.
{% endstep %}
{% endstepper %}

你也可以手动创建处理器：添加一个 **自定义事件** ，使用完全相同的动作名称和一个 `FConvaiResultAction` 参数。插件按名称分发——参见 [角色动作的工作方式](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unreal-engine-plugin/features/character-actions/how-character-actions-work.md).

### 处理动作完成

每个处理器都必须在动作结束、成功、失败或被中断时调用 `处理动作完成` 在该 `Convai Chatbot` 组件。若没有此调用，队列会停滞，后续动作将永远不会运行。

{% hint style="info" %}
对于大多数处理器，只需 `IsSuccessful` 需要更改。其余参数属于高级选项——在你需要来自角色的语音反馈之前，将它们保持为默认值。
{% endhint %}

| 参数               | 默认     | 用途                                     |
| ---------------- | ------ | -------------------------------------- |
| `IsSuccessful`   | `true` | `true` 会出队当前动作并开始下一个。 `false` 会清空剩余队列。 |
| `bAutoReport`    | `true` | 当 `true`，会向 Convai 发送默认结果消息。           |
| `ShouldRespond`  | `从不`   | 控制 Convai 是否会口头说明结果。                   |
| `AdditionalNote` | `""`   | 附加到自动生成消息后的可选文本。高级引脚。                  |
| `延迟`             | `0.0`  | 在下一动作开始前等待的秒数。高级引脚。                    |

#### 何时更改自动报告

对于不需要口头后续的简单动作，将 `bAutoReport` 保持默认，或将 `ShouldRespond` 设为 `从不`设为

在以下情况下禁用或调整 `bAutoReport` ：

* 该动作是仅用于调试或 UI 的步骤（例如 `Print`).
* 你希望 Convai 口头确认失败——将 `ShouldRespond` 设为 `始终` 并提供一个 `AdditionalNote`.

#### 每条退出路径上的完成调用

连接 `处理动作完成` 在所有分支上：

* 动作完成后的成功路径。
* 当不满足前置条件时的失败路径。
* 当一个延迟动作（动画蒙太奇、计时器、移动）被取消时的中断路径。

```
// Blueprint 伪代码 — Print 处理器
事件 Print(ActionData: FConvaiResultAction)
    Print String("This is the print action")
    HandleActionCompletion(
        IsSuccessful = true,
        bAutoReport = true,
        ShouldRespond = Never
    )
```

### AbortActionSequence

当处理器无法恢复时——目标 Actor 已被销毁、蒙太奇播放失败、前置条件永久不满足——调用 `AbortActionSequence` 而不是使用 `Handle Action Completion(false)`.

| 参数              | 默认     | 用途                                 |
| --------------- | ------ | ---------------------------------- |
| `EventText`     | `""`   | 对失败原因的描述。留空会导致静默中止。                |
| `ShouldRespond` | `Auto` | Convai 应如何响应。使用 `始终` 当角色应当口头确认失败时。 |

### 使用 On Actions Received 观察动作

绑定到 **On Actions Received** 聊天机器人组件上的此委托，以记录或调试原始动作序列。该委托不会取代基于名称的分发——插件仍会自动调用匹配的处理器。

```
// Blueprint 伪代码
On Actions Received(
    ChatbotComponent: UConvaiChatbotComponent,
    InteractingPlayerComponent: UConvaiPlayerComponent,
    SequenceOfActions: TArray<FConvaiResultAction>
)
```

将此委托用于诊断，而不是替代逐个动作的处理器。

### 示例：Open Door 处理器

```
// Blueprint 伪代码
事件 Open Door(ActionData: FConvaiResultAction)
    TargetEntry = GetParamAsRef(ActionData, "target")
    DoorActor = TargetEntry.Ref

    如果 DoorActor 无效：
        AbortActionSequence(
            EventText = "门的目标缺失",
            ShouldRespond = Always
        )
        return

    在 DoorActor 上调用 OpenAnimation
    延迟 1.5 秒

    HandleActionCompletion(
        IsSuccessful = true,
        bAutoReport = true,
        ShouldRespond = Never
    )
```

### 下一步

{% content-ref url="/pages/e29ff52f0d30b08b7f190e5b10f7b84aa21c7ff4" %}
[参数化动作](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unreal-engine-plugin/features/character-actions/parameterized-actions.md)
{% endcontent-ref %}

{% content-ref url="/pages/8e18d509947b40274dca96b384f432486348198f" %}
[Actions Blueprint 参考](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unreal-engine-plugin/features/character-actions/actions-blueprint-reference.md)
{% endcontent-ref %}

{% content-ref url="/pages/667b43e0827e11f62e187182ca1631dcc064fb61" %}
[角色动作示例](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unreal-engine-plugin/features/character-actions/character-actions-examples.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-unreal-engine-plugin/features/character-actions/building-custom-action-handlers.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.
