亲宝软件园·资讯

展开

UE4 Unlua 调用AIMoveTo

npchaha 人气:0

引言

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

注意:异步节点可以在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

加载全部内容

相关教程
猜你喜欢
用户评论