UE4 Unlua 调用异步蓝图节点AIMoveTo函数示例详解

目录
  • 引言
  • 源码分析
  • Unlua代码实现

引言

异步蓝图节点:在蓝图节点的右上角有时钟图标。

注意:异步节点可以在EventGraph/Macros中使用,但是无法在蓝图函数中使用。

AIMoveTo节点:实现AI自主寻路,且能异步回调执行成功或失败的委托函数,且返回移动结果枚举值。

源码分析

AIMoveTo 蓝图节点对应C++的基类为 UK2Node_AIMoveToUK2Node_AIMoveTo 继承至异步Task节点基类 UK2Node_BaseAsyncTask,并在构造函数中完成了对该异步基类的实例化
代码如下:

UK2Node_AIMoveTo::UK2Node_AIMoveTo(const FObjectInitializer& ObjectInitializer)
    : Super(ObjectInitializer)
{
    ProxyFactoryFunctionName = GET_FUNCTION_NAME_CHECKED(UAIBlueprintHelperLibrary, CreateMoveToProxyObject);   //确定异步调用的函数名
    ProxyFactoryClass = UAIBlueprintHelperLibrary::StaticClass();                                               //包含异步函数实现的类
    ProxyClass = UAIAsyncTaskBlueprintProxy::StaticClass();                                                     //将会被实例化的类
}

从上述代码中可以知道,AIMoveTo主要调用的函数为UAIBlueprintHelperLibrary类中的CreateMoveToProxyObject方法。

查看源码,发现CreateMoveToProxyObject方法返回值的就是一个UAIAsyncTaskBlueprintProxy实例。

以下截取部分关键代码进行分析(MyObj就是新建的UAIAsyncTaskBlueprintProxy实例):

UAIAsyncTaskBlueprintProxy* UAIBlueprintHelperLibrary::CreateMoveToProxyObject(UObject* WorldContextObject, APawn* Pawn, FVector Destination,
AActor* TargetActor, float AcceptanceRadius, bool bStopOnOverlap)
{
            ……
        FPathFollowingRequestResult ResultData = AIController->MoveTo(MoveReq);     //调用AIController相关函数进行寻路
        switch (ResultData.Code)
        {
        case EPathFollowingRequestResult::RequestSuccessful:
            MyObj->AIController = AIController;
            MyObj->AIController->ReceiveMoveCompleted.AddDynamic(MyObj, &UAIAsyncTaskBlueprintProxy::OnMoveCompleted);  //寻路请求完成后,触发OnCompleted函数
            MyObj->MoveRequestId = ResultData.MoveId;
            break;
            ……
        }
            ……
    return MyObj;
}

再看 OnMoveCompleted 函数:该函数可触发两个多播委托 OnSuccessOnFail,正好是 AIMoveTo 节点的两个异步回调引脚名:

void UAIAsyncTaskBlueprintProxy::OnMoveCompleted(FAIRequestID RequestID, EPathFollowingResult::Type MovementResult)
{
    if (RequestID.IsEquivalent(MoveRequestId) && AIController.IsValid(true))
    {
        AIController->ReceiveMoveCompleted.RemoveDynamic(this, &UAIAsyncTaskBlueprintProxy::OnMoveCompleted);
        if (MovementResult == EPathFollowingResult::Success)
        {
            OnSuccess.Broadcast(MovementResult);        //广播事件OnSuccess
        }
        else
        {
            OnFail.Broadcast(MovementResult);           //广播事件OnFail
            // ……
        }
    }
}

而这两个委托都是在类 UAIAsyncTaskBlueprintProxy 中声明的蓝图可分配委托:

UPROPERTY(BlueprintAssignable)
FOAISimpleDelegate    OnSuccess;
UPROPERTY(BlueprintAssignable)
FOAISimpleDelegate    OnFail;

总结:CreateMoveToProxyObject 函数实现寻路,UAIAsyncTaskBlueprintProxy 定义委托。

Unlua代码实现

关键代码:

function BTT_FuncName_C:ReceiveExecuteAI(OwnerController,ControlledPawn)
    ……
    --调用CreateMoveProxyObject函数实现寻路并返回UAIAsyncTaskBlueprintProxy实例
    local MoveResult = UE4.UAIBlueprintHelperLibrary.CreateMoveToProxyObject(ControlledPawn,ControlledPawn,DesLocation)
    --在返回的实例中,绑定委托相关回调函数
    MoveResult.OnSuccess:Add(self,BTT_FuncName_C.OnAIMoveSuccess)
end
--实现回调函数
function BTT_FuncName_C:OnAIMoveSuccess(MovementResult)
    print("寻路成功")
    self:FinishExecute()
end

以上就是UE4 Unlua 调用AIMoveTo函数示例详解的详细内容,更多关于UE4 Unlua 调用AIMoveTo的资料请关注我们其它相关文章!

(0)

相关推荐

  • C/C++ Qt TreeWidget 嵌套节点操作使用

    目录 简单的节点遍历 初始化树形节点 单击双击节点反馈 添加 父节点/子节点 删除选中节点 修改指定节点名称 枚举所有节点元素 枚举选中节点元素 获取选中子节点的父节点 在上一篇博文<C/C++ Qt TreeWidget 单层树形组件应用>中给大家演示了如何使用TreeWidget组件创建单层树形结构,并给这个树形组件增加了右键菜单功能,接下来将继续延申树形组件的使用,并实现对树形框多节点的各种操作. 常用树形框节点间的操作方法如下: 节点遍历 初始化节点 单击双击节点 添加根节点 添加子节

  • C++ boost::asio编程-异步TCP详解及实例代码

    C++ boost::asio编程-异步TCP 大家好,我是异步方式 和同步方式不同,我从来不花时间去等那些龟速的IO操作,我只是向系统说一声要做什么,然后就可以做其它事去了.如果系统完成了操作, 系统就会通过我之前给它的回调对象来通知我. 在ASIO库中,异步方式的函数或方法名称前面都有"async_ " 前缀,函数参数里会要求放一个回调函数(或仿函数).异步操作执行 后不管有没有完成都会立即返回,这时可以做一些其它事,直到回调函数(或仿函数)被调用,说明异步操作已经完成. 在ASI

  • C++链表节点的添加和删除介绍

    目录 前言 1. 节点的创建 2. 链表的定义 3. 创建节点 4. 节点的插入 4.1 头插法 4.2 尾插法 4.3 插入中间节点 总结 前言 链表是一种动态的数据结构,因为在创建链表时,不需要知道链表的长度,只需要对指针进行操作. 1. 节点的创建 链表的节点包括两部分,分别是:数据域和(指向下一个节点的)指针域. struct Node { int data; struct Node* next; }; 2. 链表的定义 struct Node* createList() { //创建一

  • C++ 线程(串行 并行 同步 异步)详解

    C++  线程(串行 并行 同步 异步)详解 看了很多关于这类的文章,一直没有总结.不总结的话就会一直糊里糊涂,以下描述都是自己理解的非官方语言,不一定严谨,可当作参考. 首先,进程可理解成一个可执行文件的执行过程.在ios app上的话我们可以理解为我们的app的.ipa文件执行过程也即app运行过程.杀掉app进程就杀掉了这个app在系统里运行所占的内存. 线程:线程是进程的最小单位.一个进程里至少有一个主线程.就是那个main thread.非常简单的app可能只需要一个主线程即UI线程.

  • C++异步操作future和aysnc与function和bind

    目录 异步操作 std::future和std::aysnc 介绍 std::future和std::aysnc的使用Demo std::packaged_task 介绍 std::packaged_task的使用Demo std::promise 的介绍 std::promise的使用Demo function和bind function的用法 bind的用法 异步操作 C++11为异步操作提供了4个接口 std::future : 异步指向某个任务,然后通过future特性去获取任务函数的返

  • UE4 Unlua 调用异步蓝图节点AIMoveTo函数示例详解

    目录 引言 源码分析 Unlua代码实现 引言 异步蓝图节点:在蓝图节点的右上角有时钟图标. 注意:异步节点可以在EventGraph/Macros中使用,但是无法在蓝图函数中使用. AIMoveTo节点:实现AI自主寻路,且能异步回调执行成功或失败的委托函数,且返回移动结果枚举值. 源码分析 AIMoveTo 蓝图节点对应C++的基类为 UK2Node_AIMoveToUK2Node_AIMoveTo 继承至异步Task节点基类 UK2Node_BaseAsyncTask,并在构造函数中完成了

  • Python模块glob函数示例详解教程

    目录 本文大纲 支持4个常用的通配符 1)glob()函数 2)iglob()函数 3)escape()函数 总结 本文大纲 glob模块也是Python标准库中一个重要的模块,主要用来查找符合特定规则的目录和文件,并将搜索的到的结果返回到一个列表中.使用这个模块最主要的原因就是,该模块支持几个特殊的正则通配符,用起来贼方便,这个将会在下方为大家进行详细讲解. 支持4个常用的通配符 使用glob模块能够快速查找我们想要的目录和文件,就是由于它支持*.**.? .[ ]这三个通配符,那么它们到底是

  • JS的时间格式化和时间戳转换函数示例详解

    JS的时间格式化和时间戳转换函数 //格式化时间 function dateFormat(fmt,date){ var o = { "M+" : date.getMonth()+1, //月份 "d+" : date.getDate(), //日 "h+" : date.getHours(), //小时 "m+" : date.getMinutes(), //分 "s+" : date.getSeconds

  • C语言大厂面试技巧及strcpy()函数示例详解

    目录 1.什么是优秀的代码? 2.常见的coding技巧有哪些? 3.以模拟实现strcpy为例 (1)了解strcpy()函数 (2)正片开始(危) 1.第一阶段(面试官:最多5分) 2.第二阶段(面试官:最多7分) 3.第三阶段的代码:(面试官:最多8分) 4.第四阶段(面试官:完美代码!10分!) 1.什么是优秀的代码? 1. 代码运行正常 2. bug很少 3. 效率高 4. 可读性高 5. 可维护性高 6. 注释清晰 7. 文档齐全 2.常见的coding技巧有哪些? 1. 使用ass

  • numpy中hstack vstack stack concatenate函数示例详解

    目录 大纲 1.concatenate() 2.stack() 3.vstack() 4.hstack() 5.tf中的stack() 大纲 本文主要介绍一下numpy中的几个常用函数,包括hstack().vstack().stack().concatenate(). 1.concatenate() 我们先来介绍最全能的concatenate()函数,后面的几个函数其实都可以用concatenate()函数来进行等价操作. concatenate()函数根据指定的维度,对一个元组.列表中的li

  • Mysql TIMESTAMPDIFF函数示例详解

    TIMESTAMPDIFF函数用于计算两个日期的时间差 语法结构 TIMESTAMPDIFF(unit,datetime_expr1,datetime_expr2) 参数说明 unit: 日期比较返回的时间差单位,常用可选值如下: SECOND:秒 MINUTE:分钟 HOUR:小时 DAY:天 WEEK:星期 MONTH:月 QUARTER:季度 YEAR:年 datetime_expr1: 要比较的日期1 datetime_expr2: 要比较的日期2 TIMESTAMPDIFF函数返回da

  • iframe调用父页面函数示例详解

    window.parent.xxxxx();//xxxxx()代表父页面方法 具体列子如下,其中包括easyUI的右键和单击事件 parent.jsp body部分代码 <body class="easyui-layout"> <!-- 左侧目录 --> <div data-options="region:'west',split:true,title:'主题',iconCls:'icon-arrowIn'" style="w

  • ECharts图表使用及异步加载的特性示例详解

    目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展.开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互.性能.数据处理等方面有更高的要求. chart.setOption({ color: [ '#c23531', '#2f4554', '#61a0a8', '#d48265', '#91c7ae', '#749f83', '#ca8622', '#bda29a', '#6e7074', '#546570', '#c4ccd3' ], // ...

  • JavaScript学习笔记之惰性函数示例详解

    前言 本文主要给大家介绍了关于JavaScript惰性函数的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. 需求 我们现在需要写一个 foo 函数,这个函数返回首次调用时的 Date 对象,注意是首次. 解决一:普通方法 var t; function foo() { if (t) return t; t = new Date() return t; } 问题有两个,一是污染了全局变量,二是每次调用 foo 的时候都需要进行一次判断. 解决二:闭包 我们很容易想到用闭

  • kotlin Standard中的内联函数示例详解

    let.with.run.apply.also.takeIf.takeUnless.repeat函数的使用 kotlin Standard.kt文件中,提供了一些内联函数,这些内联函数可以减少代码量,在使代码优美的同时,打打提高开发效率.它们分别为: run.with.let.also.apply let let函数的定义如下: public inline fun <T, R> T.let(block: (T) -> R): R = block(this) 默认当前这个对象作为闭包的it

随机推荐