> 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/unreal-engine-plugin-beta-overview/convai-actions/phase-2-custom-actions.md).

# 阶段 2：自定义动作

第 1 阶段使用了四个已随包提供的默认动作。现在你将添加你自己的 **动作** ，不带任何参数，并将其连接到一个 Blueprint 事件。到本阶段结束时，让机器人请求 *“print hello”* 就会运行你的 Blueprint 代码。

### 你需要什么

* 第 1 阶段的设置已正常工作——关卡中有聊天机器人， `启用动作` 已勾选，NavMesh 已就位，角色移动系统已设置好。
* 角色 Blueprint 资产已打开（或可访问）。

### 步骤 1 — 声明动作模板

1. 选择关卡中的 Convai 角色 Actor。
2. 在 Details 面板中，找到 **Convai 聊天机器人** 组件 → **Convai → Actions → Environment → Actions**.
3. 点击 **`+`** 以添加新条目。UE 会展开一个 `FConvaiAction` 结构体。
4. 填写：
   * **名称**: `Print` （这是你的处理程序将分发所依据的规范动作名称）。
   * **描述**: `向屏幕打印一条调试消息`.
   * 保持 **`参数`** 为空。

该 **`渲染后的字符串`** 下方字段会自动填充为：

```
Print — 向屏幕打印一条调试消息。
```

这就是发送给 LLM 的线格式字符串。你在编辑 Name 或 Description 时，渲染后的字符串会实时更新。

### 步骤 2 — 在 Blueprint 中绑定处理程序

聊天机器人会触发 `OnActionReceivedEvent_V2` ，每当机器人决定执行动作时都会触发。你在角色的 Blueprint 中对它作出响应。

1. 打开你的角色 Blueprint。
2. 在 **Components** 选项卡，点击 **Convai 聊天机器人** 组件将其选中。
3. 在 **详细信息** 该组件的面板中，找到 **事件** 类别。点击 **`+`** 旁边的 **`On Action Received Event V2`**。UE 会将一个已绑定的事件拖入 Event Graph。
4. 该事件会提供一个 **`动作序列`** 数组（每一项都是一个 `FConvaiResultAction`）以及聊天机器人组件和正在交互的玩家组件的引用。

### 步骤 3 — 按动作名称分发

在这个已绑定的事件内部， **对于数组中的每个** 动作：

1. **获取** `动作` （规范名称字符串）。
2. **按字符串分支** 并为你声明的每个动作设置 case：
   * `Print` → 调用你的自定义逻辑，然后 `Handle Action Completion(Is Successful=true, Delay=0)`.
   * **默认值** → 调用 `Handle Action Completion(Is Successful=true, Delay=0)` 以保持队列继续前进（或者让未处理的动作重试——那是一个 `Is Successful=false` 的情况）。

对于 `Print` 情况：

1. 拖出一个 **`打印字符串`** 节点，从执行引脚拉出并给它一个字面量 `“Hello from Convai!”` （或者从 Action 中读取——但在本阶段该动作没有参数）。
2. 在打印之后，拖入 **`Handle Action Completion`** ，从聊天机器人引用上拖出。设置：
   * **Is Successful**: `true` （该动作已运行）。
   * **Delay**: `0`.
   * 保持 **Event Text** 留空（高级字段）——当你希望把一个结果回写到机器人动态上下文中时使用。留空 = 无事件。

这就是完整的处理程序。机器人现在知道如何执行 `Print`.

### 步骤 4 — 运行测试

按下 **Play** 并向角色提问： *“Print hello.”*

在编辑器的视口中，你应该会看到 `“Hello from Convai!”` （或你使用的任何字面量）通过 Print String 显示出来。机器人也会口头回应它的确认。

### 整个流水线如何端到端运行

当 LLM 发出一个动作时：

1. 服务器发送 `{name: "Print"}` （无目标，无参数）。
2. 插件的解析器会在你的 `Print` 中按名称找到 `Environment.Actions`.
3. 由于该模板没有声明参数， `参数` 会保持为空。
4. `OnActionReceivedEvent_V2` 会在聊天机器人上触发，并带着解析后的序列。
5. 你的 Blueprint 会按 `Action == "Print"` 进行分发并执行打印。
6. `Handle Action Completion(true, 0)` 推进队列。如果序列中还有更多动作，下一个现在就会运行。

### 为什么要有队列

机器人可以在一次回复中发出 **一个动作序列** ，例如 *“等待 2 秒，然后走到立方体旁，再打印完成。”* 队列会确保每个动作在下一个开始之前完成。你的处理程序负责告诉队列当前动作何时完成——这就是 `Handle Action Completion` 所做的。

| 调用                                    | 效果                    |
| ------------------------------------- | --------------------- |
| `Handle Action Completion(true, 0)`   | 将当前动作标记为成功，立即运行下一个。   |
| `Handle Action Completion(true, 1.5)` | 成功，但在下一个动作之前等待 1.5 秒。 |
| `Handle Action Completion(false, 0)`  | 重试同一个动作。              |

你也可以在同一次调用中把一个结果事件推入机器人上下文——这对叙述很有用：

```
Handle Action Completion(true, 0, EventText="Printed the message", ShouldRespond=Auto)
```

### 当事情出错时

如果你的处理程序无法恢复（目标已经消失，前置条件失败），不要无限重试—— **中止整个序列** 并让 LLM 重新规划：

```
Abort Action Sequence(EventText="Couldn't print — screen is off", ShouldRespond=Always)
```

这会清除剩余的排队动作，并触发一个上下文事件，让 LLM 做出确认，并很可能在下一轮发出新的动作计划。

### 回顾

你添加了一个动作模板，编写了一个处理程序，并让机器人开始执行自定义操作。下一步是 **类型化参数** ——告诉 LLM 一个动作接受一个数字、一个 Actor 引用，或者 N 选 1 的选项。继续进入第 3 阶段——参数化动作。


---

# 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/unreal-engine-plugin-beta-overview/convai-actions/phase-2-custom-actions.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.
