跳到正文
Convai 智能 NPC 与动态剧情· 一手来源·· 2026-09-22精选AI 评分61

自定义 Convai 操作在 Unreal Engine 中:构建一个可以拾取和放置物体的 AI 玩家(第 2 部分)

Custom Convai Actions in Unreal Engine: Build an AI Player That Picks Up and Places Objects (Part 2)

推荐理由

原文以拾取和放置两个动作为例,给出了自定义动作的声明、参数解析、失败处理和队列推进的完整接线方式,并讨论了原子动作与复合动作的设计取舍。

正文 · AI 翻译

赋予一个 AI 角色物理行动能力,最难的部分不是教会它如何成功,而是教会它如何大声地失败。

一个角色拿起箱子并将其搬运过移动平台,在演示视频中看起来令人印象深刻。但一个角色走向箱子、发现路径被阻挡、并用直白的语言说明情况的,才是你可以交付的版本,因为玩家无需打开输出日志就能知道出了什么问题。

这是 Convai AI 队友系列在 Unreal Engine 中的第二部分,基于 Epic Games的 Stack O Bot示例构建,适用于 Unreal Engine。在第一部分中,角色获得了环境感知、实时游戏状态以及内置移动动作,使其能够走向物体并站在压力板上。本部分为它增加了两个自定义动作——拾取和放置到指定位置,并将其接入项目中已有的游戏逻辑。

最终, AI 玩家接收一条语音指令,移动到木箱旁,将其举起,搬运到压力板上,放下,等待平台升起,并仅通过对话协助完成一个双人谜题。

观看本文逐步跟随的完整教程:

第一部分构建了什么,第二部分又增加了什么?

第一部分通过 Convai 的场景元数据系统注册了关卡,使角色知道哪些对象存在;添加了跟踪属性,使其知道哪些压力板处于激活状态;并依赖插件自带的四个内置操作处理器。

这些内置功能,在角色动作中心中有详细介绍,能覆盖很广的范围。它们并不涵盖拾取物品的功能,因为没有任何插件能够了解在你的项目中"拾取"意味着什么。Stack O Bot 拥有自己的交互系统,该系统在 Convai 出现之前就已编写完成,而第二部分的内容是深入该系统而非将其替换。

这就是任何项目中 自定义操作的一般形式。Convai 负责处理意图、 目标解析和报告。你的 蓝图负责处理与你的游戏相关的特定部分。

如果你是全新开始, Stack O Bot 教程设置指南将逐步介绍如何在 Unreal Engine 5.8中创建项目,并将教程的 delta 文件复制覆盖到该项目上。你还需要从 Fab获取 Convai Unreal Engine 插件,以及一个 已安装并登录的编辑器。

在此观看本教程第一部分的完整内容:

在编写自定义动作之前值得做的两处设置修复

第一部分留下了两处不够完善的地方。两者都很小,但都会影响自定义动作的可靠程度。

给压力板添加一个运动点

当角色移动到压力板时,有时会在边缘附近停下,而不是站在板上。压力板被注册为一个对象,因此移动解析器在其碰撞边界处停止,这对于宽对象来说是正确的默认行为,但在这里却是错误的。

修复方法是添加一个移动点。打开压力板的 Blueprint,进入视口,选中 Convai Object Component,然后在对象条目下添加一个移动点。将其向上微调,使其位于板的顶部。视口中的绿色箭头会显示角色将站立的位置,Convai Debug Overlay 会在运行时稍后确认这一点。

移动点是由设计师创建的目的地,Convai 的解析器会选择步行路径最短的可到达点,而非对象的原始位置。每个点渲染为一个可抓取手柄,带有接受半径环,启用时为春绿色,禁用时为灰色。由于所有压力板共享同一个蓝图,该点会复制到每个实例中。

在开始创建自己的内容时,文档中有两个细节值得了解。附着模式默认为 Relative To Object,这是压板或门所需要的,而 Keep World Position 则适合像电梯层这样需要在平台经过时保持不动的物体。勾选 Create Separate Destination 会将一个点变成其自身可寻址的目标,因此一个名为 Other Side 的点在名为 Door 的物体上,就会成为一个角色可以通过名称被送往的目的地。

将移动平台的状态作为可跟踪属性暴露

第一部分为压板添加了一个 active 变量,以便 Convai 能够读取每个压板是否被按下。移动平台没有对应的变量。

平台有一个 Toggle Platform 事件,该事件在 Actor上调用 Unreal 的 Set Actor Tick Enabled。该 Tick 状态即为平台的状态,因此可以通过 Convai Object Component下的 Tracked Properties 将其暴露出来。添加一个属性,搜索 tick,然后选择 Is Actor Tick Enabled。

重要的部分是别名。将引擎属性名称发送给语言模型只会带来噪音。将其重命名为 active,并给它一个朴素的描述,比如"为 true 时沿重复周期上下移动"。现在角色读取的是关于平台的事实,而非关于 Unreal 的 tick 系统的事实,这与在场景元数据中良好地命名和描述对象背后的道理是一样的。

每个被跟踪的属性都包含一个 Property Path、一个 Description、在 Advanced 下可选的逐值注释,以及一个 Should Respond 设置,用于控制运行时值发生变化时的行为。Should Respond 可取 Auto、Always 或 Never,会话开始时发送的初始值(seed)始终为 Never,因此角色会获知初始值而不会主动提及。动态上下文系统处理其余部分,其同步行为页面说明了批处理规则(如果你需要在特定时刻收到更新),而快速入门则是更简短的入口。

什么是 Unreal Engine 中的自定义 Convai 操作?

自定义 Convai 操作是你在 Convai Chatbot 组件上声明的具有名称和描述的功能,并配合同名的 Blueprint 事件或函数,当 Convai 选择该操作时执行。该声明在会话开始时作为 操作配置发送给 Convai。调度在运行时按名称进行。

三个部分使一个操作得以运行。模板,位于 Actions 数组中,告知 Convai 该操作的存在。处理程序,即名称与之匹配的 Blueprint 事件。以及完成调用,用于报告结果并让 操作队列继续推进。

三者中漏掉任何一个,AI NPC每次都会以不同的方式显得有问题,这就是为什么故障排除页面一打开就让你查看 Output Log。

如何使用 Actor Reference 参数来定义拾取和放置?

选中角色,打开其 Blueprint,找到Convai Chatbot 组件,然后打开 Environment 下的 Actions 部分。

添加一个名为 Pick Up 的操作。它需要知道要拾取什么,因此添加一个名为 target 的参数。target 将是场景中的一个对象,所以将其类型设为 Actor Reference,这与内置处理器用于其目标位置的类型相同。

添加第二个名为 Drop At 的动作。它接收角色已经持有的物品并将其放到某个位置,因此添加一个名为 destination 的参数,类型同样为 Actor Reference。

然后编写描述。不要写太长的。关于这一点,参数化动作指南说得非常直接:冗长的描述会增加发送给 Convai 的上下文,但不会改善行为表现;当名称本身已经足够说明时,留空描述是正确的。

Drop At 无论如何都值得一个描述,因为它带有一个前置条件。类似"将角色已拾取的物体放置在指定目的地"这样的措辞会告诉模型,持有某物是前提条件,这决定了模型何时才会使用该动作。描述中的前置条件提示是整个系统中成本最低的可靠性工作,而示例页面展示了几个写好的例子。

编辑任何动作模板后,请编译角色蓝图。在播放模式下从未出现的新动作,几乎总是未编译的模板,故障排除页面将其列为自身的症状。

为什么使用 Actor 引用而不是普通字符串?

Convai 支持六种参数类型:String、Actor Reference、Number、Bool、带有固定 Choices 列表的 String,以及绑定到项目 UENUM 的 Enum。完整的类型行为表位于 Blueprint 参考文档中。

Actor Reference 通过精确名称在你的已注册 Objects 和 Characters 数组中进行解析。这种解析本身就是其价值所在。String 参数只会把单词 crate 交给你,然后让你自己去找到那个 crate,而这正是scene metadata已经替你完成的那种查找。Reference 参数则直接把条目交给你,这意味着一个实时的 Actor 指针、一个接受半径、任何已编辑的移动点,以及你为该模型撰写的描述。

教程通过将目标也设为 Actor Reference 来保持 drop-at 的简洁。更通用的实现可能让角色对一个位置而非一个已注册对象进行推理,这是一个真正的设计分支,而非取巧。已注册对象是精确且有限的。自由位置更灵活,但也更难验证,这就是为什么空间感知在一个中心位置统一计算距离和可达性。

需要规划的一个后果:引用解析只搜索已注册的环境,不会搜索其他任何地方。如果 Convai 返回的名称与已注册的条目不匹配,Get Param As Ref 将返回一个空条目。简短、有辨识度的已注册名称比任何人格或提示词更改都能解决更多此类问题,而注意力与引用锚定则涵盖了当两个对象在模型看来相似时该如何处理。

如何在 Blueprint 中搭建一个动作处理器?

在角色 Blueprint 的Event Graph的空白区域右键单击,搜索 Create Convai Action Handler。选择 Pick Up 并确认。对 Drop At 重复此操作。

编辑器工具会生成一个与操作名称匹配的处理程序,为其提供一个 Convai Result Action输入,并在末尾连接一个 Handle Action Completion 调用。你可以选择事件图上的一个事件,或选择其自身图中的函数。

你也可以手动构建处理程序,使用与操作名称完全一致的自定义事件和一个 Convai Result Action 参数,因为分发是按名称进行的。无论如何,还是请使用该工具。处理程序名称不匹配和参数签名错误是操作从未触发的两个最常见原因,当编辑器为你编写节点时,这两个问题都会消失。Unreal 解析处理程序名称时不区分大小写,但 Stop Moving 和 StopMoving 仍然是两个不同的名称。

在 Pick Up 内部,Convai Result Action 结构体承载参数。使用 Get Param As Ref 拉取目标,输入 target 以匹配声明的名称。这会返回一个包含你所需引用以及若干不需要的字段的结构体,因此折叠掉未使用的字段,保持节点图的可读性。

该访问器库提供 Get Param As String、As Number、As Bool、As Ref、As Byte(用于枚举),此外还有 Has Param 作为守卫,以及 Get First Param 用于单参数操作,并在其上叠加了选项和枚举处理。

Handle Action Completion 控制什么?

每个处理函数都必须在每条退出路径上调用它。没有这个调用,操作队列就会停滞,后续操作永远不会执行。

它接受五个输入。Is Successful,默认为 true,控制队列是推进还是清空。Auto Report,向 Convai 发送默认的结局消息。Should Respond,决定角色是否对结局进行口头回应,接受 Auto、Always 或 Never。Additional Note,一个高级引脚,用于附加到生成消息末尾的文本。以及 Delay,下一个动作开始前的等待秒数。

大多数处理器只修改其中一项。其余的保持默认值,直到你需要口头反馈为止。

有一个值得了解的兄弟节点。中止操作序列会清空队列,并接收一个事件文本和一个是否响应的选项。官方建议是:当处理程序完全无法恢复时使用它,例如目标 Actor 已被销毁,或某个前置条件永远无法满足;而对于角色可能会重试或试图绕过去的结果,则应使用将 Is Successful 设为 false 的 Handle Action Completion。教程对移动失败使用了后一种形式,这是合适的:路径被阻挡是角色可以描述并重新尝试的情况。

自定义操作是否应该是原子的?

这就是教程中暂停讨论的那个设计问题,也是整个视频中最具可迁移性的概念。

原则上,每个动作只做一件事。Move To 负责移动,Pick Up 负责拾取。Convai 将它们编排为序列,因为编排正是规划器的职责所在。这就是将原子性应用于智能体可供性,并且有明确的回报:如果 Pick Up 因角色距离太远而失败,该失败是清晰可辨的。报告时附上备注说明角色不在目标附近,模型便可决定先靠近再重试。

教程故意采用了另一种做法。Pick Up 先移动到目标位置,然后再拾取。更少的节点、更少的往返、更少的序列在谜题中途断裂的风险。

两种选择都有道理,而其中的取舍值得明确点出。原子动作给模型留出恢复空间,让它组合出你并未编写脚本的行为。复合动作则给你确定性,以及更少的活动部件。在无法预判操作顺序的开放场景中,原子动作往往更胜一筹,例如训练模拟、多人世界,或开放世界中的 NPC 行为。而在你已知任务形态的紧凑编排序列中,复合动作往往更胜一筹。

你应该避免的是在毫无察觉中做出选择。一个用单个布尔值掩盖三种失败模式的复合动作,就是那个凌晨两点被调试的版本。

如何将 Convai Move To 接入自定义动作?

Convai Move To 是 Convai Movement 类别中的一个潜在蓝图节点。它接收一个 Moving Actor 和一个目标位置条目,可以解析整个 Actor、特定组件、插槽以及预设的移动点,无需手动连接 Resolve Goal Location 线。

对于 Pick Up,将 Moving Actor 设置为 self,并将 target 参数中的引用作为目标位置传入。

该节点有两个执行输出。Succeeded 在 Reached 或 Already At Destination 时触发。Failed 在所有其他情况下触发。它还返回一个 Result Code 和一个 Additional Note,文档说明可以安全地将其传递给 Handle Action Completion 或向玩家播报。

那个 Result Code 枚举比大多数人预期的信息量更大。它区分了 Reached、Already At Destination、Unknown Destination、Unreachable、Invalid Character、Missing AI Controller、Missing Movement Component、Missing Path Following Component、Missing Navigation Data 和 Move Failed。这十个中有四个指向的是配置问题而非世界状态,这使得该枚举既是运行时信号,也是调试工具。

在 Failed 分支上,复制 Handle Action Completion,将 Is Successful 设为 false,报告结果,要求返回响应,并传递 Additional Note。这里要求返回响应很重要。一个无法到达箱子的角色接下来没有有用的事情可做,因此它应该说出来,而不是站在那里让玩家怀疑游戏引擎是否卡住了。

如果移动失败的方式被枚举归因于设置问题,常见原因包括:导航网格未覆盖两个端点、缺少 AI Controller 类,或 pawn 移动从未被配置。针对最后一种情况,插件在角色蓝图的上下文菜单中提供了 Setup Convai Pawn Movement 工具;针对第一种情况,则可使用Build Paths配合 P 键在视口中进行寻路可视化。

如何将 Convai 动作连接到现有的游戏系统?

正是在这里,自定义动作不再只是通用的,而开始真正属于你的项目。

Stack O Bot 的交互系统早在任何 AI 介入之前就已编写完成,其中使用了一个名为 Potential Interact 的变量。要拾取某样东西,角色会设置其 Potential Interact,然后调用项目自身的 Interact 函数。

有一个坑,而且是那种会吃掉一下午的。Potential Interact 期望的是箱子内部的组件,而非箱子 Actor 本身。打开箱子的 Blueprint,你要找的组件就是它的静态网格体。因此,从目标引用出发,使用 Get Component By Class 获取静态网格体组件,将其设置为 Potential Interact,然后调用 Interact,并确认该版本解析到的是 AI 机器人 Blueprint 而非同级节点。

这一经验可以推广到本项目之外。在编写自定义动作之前,先阅读你要接入的系统,弄清楚它期望输入是什么形式。Convai 那部分工作只需几分钟。集成那部分则取决于现有代码有多特殊,而每个游戏玩法代码库总会在某处有其独特之处。一个具备场景标记和项目访问权限的助手可以缩短这一步。

这也是Convai 面向 Unreal 的 MCP 工作流发挥作用的地方,因为一个能够读取你项目结构的助手可以缩短发现步骤。

另请参阅:Convai 面向 Unreal Engine 的 MCP,即本系列中用于搭建场景的工作流。

如何实现 drop-at 动作?

Drop At 的起始方式相同。使用 Get Param As Ref 读取目标位置,将其传入 Convai Move To,并通过 Handle Action Completion、Is Successful false 以及该节点的 Additional Note 来处理 Failed 分支。

掉落本身需要先加一个保护。

Stack O Bot 会保留角色当前持有物品的引用。在掉落任何东西之前,先检查该引用是否有效。右键点击它并选择 Convert To Validated Get,这会将图分为有效分支和无效分支。

在无效分支上,角色手中没有任何物品,因此"放下到"操作会失败。调用"处理动作完成",附带一条消息,例如"你没有拿起任何可以放下的物品",并要求角色做出回应,以便角色说出这句话。那句话就是守卫条件的完整值。没有它,该动作会静默返回 false,玩家得不到任何解释。

在有效分支上,放置该物体。获取目标引用,获取其位置,并在其上方构建一个新位置,因为将箱子放入压力板内不是任何人想要的结果。偏移量应用于 Z 轴。教程在 Z 轴上增加了 100 个单位。

然后获取箱子本身。图中持有的是一个静态网格组件,因此 Get Owner 返回拥有它的 Actor。将该 Actor 传入 Set Actor Location 并附带偏移位置,再次调用 Stack O Bot 的 Interact 函数以释放持有,最后以 Handle Action Completion 标记为成功来结束。

这就是全部实现。两个动作,两个参数,移动各有一个守卫,持有状态有一个守卫。

为什么失败状态比成功状态更重要

看看这两个处理器的节点都花在了什么地方。每个图中大约一半的节点用于失败处理,而这个比例并非偶然。

成功路径塑造出一个在世界配合时能正常运作的角色。失败路径塑造出一个在世界不配合时仍能留在对话中的角色,这本质上就是异常处理,只不过附带了一个声音。动作队列在设计上强制执行了其中一部分,因为当 Is Successful 设为 false 时,它会清空剩余队列,而不是继续推进一个第一步尚未执行的计划。

故障排除指南列出了团队容易遗忘的退出路径:在任务开始之前就返回的守卫条件退出、完成调用位于不可达分支中的异步回调,以及从未将 On Interrupted 与 On Completed 同时接线的动画蒙太奇。最后一种是经典问题,它会让队列停滞,因为插件在等待一段已被取消的舞蹈。

在每个完成调用之前放置一个 Print String 节点,然后确认每条路径都能到达其中一个,只需五分钟,却能节省大量时间。Convai Debug Overlay 对移动点执行同样的工作,在世界空间中为每个已命名且已启用的点绘制一个标记。

完成的谜题运行起来是什么样子?

这次测试运行是一个双人 Stack O Bot 谜题,任何一位玩家都无法独自解开。

玩家要求 AI 队友按住一个压力板,以便自己爬上去并扔下一个板条箱。角色同意了,说明它正前往哪块板,然后出发了。当板条箱落在它附近时,角色注意到了,并询问它是应该捡起板条箱,还是玩家另有打算。被告知用板条箱压住压力板后,它回答说这个计划可以让它自由移动,随后放好板条箱,并在平台稳定后报告了平台状态。

那些对话没有一句是预先编写的。被预先编写的是角色能够读取的环境,以及它可以执行的两个动作。这段对话是当这两部分被同时指定时所产生的结果,这与背后的非线性叙事设计的配对方式相同。

值得回看的时刻是角色询问是否要捡起那个箱子。它具备能力,也有目标,但它还是问了,因为一个箱子落在它附近是世界的变化,而非一条指令。这种行为来自第一部分中设置的跟踪属性和场景元数据,而非第二部分的动作处理器。感知与能动性是两套独立的系统,只有两者同时存在时,角色才像一名队友——这一点正是注意力中的对象工作从感知层面所阐述的。

另请参阅:第一部分:实时游戏状态与场景搭建,该部分构建了本教程所扩展的感知层。

常见问题及解决方法

角色会说话,但处理程序从未运行。检查聊天机器人的 Environment 属性中是否已勾选 Enable Actions,然后检查动作模板名称是否与 Blueprint 事件名称完全匹配(包括空格)。当 dispatch 找不到处理程序时,Output Log 会报告缺失函数的警告。

处理程序存在但被跳过。该函数必须接受零个参数,或者仅接受一个 Convai Result Action,不能有其他参数。签名错误会记录一条警告,并使队列处于等待状态。

一个动作执行后序列就停止了。某条路径未调用 Handle Action Completion,或调用时 Is Successful 为 false。

新动作在 Play 模式下从未出现。编辑模板后,角色 Blueprint 未重新编译。

Get Param As Ref 返回一个空条目。该对象不在 Objects 或 Characters 数组中,或者 Convai 返回的名称与已注册的条目不匹配。你可以使用 Add Object 和 Add Character 在运行时添加条目,以及注视和注意力设置器,相关内容见运行时管理环境。

角色会走到物体附近但不会到达物体本身。要么创建一个移动点,要么将 Object Is 设置为 Specific Component,适用于按钮和拉杆等小型目标。Acceptance Radius 默认为 150 厘米,对于拉杆来说这个范围偏大。

插件更新后,一个 Blueprint 停止了编译。4.0.0-beta.27 的迁移指南列出了每个被移除的引脚和重命名的字段,以及需要应用的编辑。

对于此处未列出的任何内容,Convai 开发者论坛是提出配置问题和提交 bug 报告的地方,本教程的讨论串汇集了按相同步骤操作的人提出的问题,更广泛的指南与教程分类和第一部分讨论串也是如此。

这种模式在解谜游戏之外还能用在哪里?

拾取和放置是解谜的解决方案。它们底层的模式是通用的:声明一项能力,从场景中解析目标,调用已经拥有该行为的系统,并以角色能够表达的语言报告结果。

把木箱换成一个工具,你就得到了一个培训模拟,其中一位指导角色演示操作流程。把它换成一个产品,你就得到了一个虚拟 AI 形象在零售场景中搬运库存,通过上下文知识库调用上传的手册。把整个环境换成软件,同样的声明-解析-执行-报告循环便通过 MCP 驱动AI 驱动的操作,作用于外部工具和系统。

引擎变了,目标变了,但报告契约不变。Convai 在 Unity 中交付了相同的动作系统,但配有一套不同的执行器,而平台的多人和叙事端消费的是相同的执行结果。

对于参数系统的更深层版本,包括 Choices 列表、enum 参数、将参数与前文连接的连接器,以及动画蒙太奇处理,参数化操作文档比本教程涉及的内容更深入,该页面上还嵌入了自定义和参数化操作演练。

入门指南

从 Fab 获取 Stack O Bot 示例和 Convai 插件,按照 设置指南完成教程增量部分,并在 Playground 中 创建一个角色放入场景。在发布前,在 核心 AI 设置中调整语音和模型行为。 角色动作快速入门是从已安装插件到角色按指令移动的最短路径。

如果你对 Unreal Engine 方面还不熟悉, 插件设置教程涵盖了安装和登录步骤,这些是上述内容生效的前提。

另外观看: Convai YouTube 频道上有其余的 Unreal 和 Unity 教程系列。

常见问题

什么是 Unreal Engine 中的自定义 Convai 操作?

自定义 Convai 操作是你在 Convai Chatbot 组件的 Actions 数组中声明的一种能力,并以同名 Blueprint 事件或函数来实现。Convai 在会话开始时将声明作为操作配置接收,在对话过程中选择操作,插件在运行时按名称将调用分发到你的处理函数。

如何在 Blueprint 中创建自定义操作处理函数?

在角色 Blueprint 的 Event Graph 中右键单击,搜索 Create Convai Action Handler,选择你已声明的操作,然后选择事件或函数。编辑器工具会生成一个名称匹配的处理函数,包含一个 Convai Result Action 输入,并在末尾连接一个 Handle Action Completion 调用。

Convai 动作支持哪些参数类型?

六种类型:String(用于开放文本)、Actor Reference(用于已注册的场景对象或角色)、Number、Bool、带有固定 Choices 列表的 String,以及绑定到现有项目 UENUM 的 Enum。Actor Reference 通过精确名称在已注册的 Objects 和 Characters 数组中解析。

为什么我的自定义动作从未触发?

最常见的原因包括:聊天机器人上未开启 Enable Actions、动作名称与 Blueprint 处理函数名称不匹配(包括空格)、处理函数签名既不接受零参数也不接受单个 Convai Result Action,或者角色 Blueprint 在编辑模板后未重新编译。

为什么我的动作队列在第一个动作之后停滞?

某个处理器未在所有退出路径上调用 Handle Action Completion。最常遗漏的路径包括:工作开始前触发的守卫条件退出、异步回调,以及动画蒙太奇中未将 On Interrupted 与 On Completed 同时接线的情况。

什么时候应该使用 Abort Action Sequence 而不是 Handle Action Completion?

当处理器完全无法恢复时,应使用 Abort Action Sequence,例如目标 Actor 已被销毁或某个前置条件永远无法满足。对于角色可以描述并重试的结果(例如路径被阻挡),应使用 Handle Action Completion 并将 Is Successful 设为 false。

自定义动作是否应该是原子的?

原子动作各自只执行一件事,由 Convai 负责编排顺序,这使得失败原因清晰可辨,模型也能通过尝试不同的步骤来恢复。复合动作将多个步骤打包在一起,以获得确定性和更少的活动部件。原子动作适合开放式场景,复合动作适合精心编写的固定序列。

如何让角色站在物体上方而不是旁边?

在物体的 Convai Object Component 上添加一个移动点,并将其定位到角色应该站立的位置。移动点会替代物体引用作为移动目标,解析器会选择可达且步行路径最短的点。

如何将 Convai 动作连接到已有的游戏逻辑?

先阅读现有系统,了解它期望的输入形式。在 Stack O Bot 中,交互系统期望的是一个静态网格组件而非 Actor,因此处理程序会先对解析后的引用使用 Get Component By Class,然后再设置 Potential Interact 并调用项目自身的 Interact 函数。

来源:Convai 智能 NPC 与动态剧情 · convai.com