UE5使用外置Unlua脚本

@UE5使用外置Unlua脚本

如何下载unlua

git地址,里面有很多demo,可以去看,下面所述是我工作中所使用的一部分,重写C++函数和加载外置脚本。
https://github.com/Tencent/UnLua

如何调试unlua脚本

我使用的是vs code的lua Booster
在这里插入图片描述

简单讲解一下使用方法
首先需要将待调试的ue程序启动
点击run and debug
在这里插入图片描述
选择第一个
之后选择待调试的项目
在这里插入图片描述
等待加载一段时间,即可进行调试
hooker ready 表示加载完成
在这里插入图片描述

如何加载unlua函数

首先定义C++类 LuaLoader
.h文件

#pragma once
#include "CoreMinimal.h"
#include "Kismet/BlueprintFunctionLibrary.h"
#include "LuaFileLoader.generated.h"
UCLASS()
class UE_SIMTRAFFICFLOW_API ULuaFileLoader : public UBlueprintFunctionLibrary
{
    
    
	GENERATED_BODY()
	UFUNCTION(BlueprintCallable, meta = (DisplayName = "SetupCustomLoader", Category = "UnLua Tutorial"))
		static void SetupCustomLoader(int Index);
};

.cpp文件

#include "LuaFileLoader.h"
#include "Kismet/KismetSystemLibrary.h"
#include "Misc/FileHelper.h"
#include "UnLua.h"
bool CustomLoader1(UnLua::FLuaEnv& Env, const FString& RelativePath, TArray<uint8>& Data, FString& FullPath)
{
    
    
    const auto SlashedRelativePath = RelativePath.Replace(TEXT("."), TEXT("/"));
    FullPath = FString::Printf(TEXT("%s%s.lua"), *GLuaSrcFullPath, *SlashedRelativePath);
    if (FFileHelper::LoadFileToArray(Data, *FullPath, FILEREAD_Silent))
        return true;
    FullPath.ReplaceInline(TEXT(".lua"), TEXT("/Index.lua"));
    if (FFileHelper::LoadFileToArray(Data, *FullPath, FILEREAD_Silent))
        return true;
    return false;
}
bool CustomLoader2(UnLua::FLuaEnv& Env, const FString& RelativePath, TArray<uint8>& Data, FString& FullPath)
{
    
    
    const auto SlashedRelativePath = RelativePath.Replace(TEXT("."), TEXT("/"));
    const auto L = Env.GetMainState();
    lua_getglobal(L, "package");
    lua_getfield(L, -1, "path");
    const char* Path = lua_tostring(L, -1);
    lua_pop(L, 2);
    if (!Path)
        return false;
    TArray<FString> Parts;
    FString(Path).ParseIntoArray(Parts, TEXT(";"), false);
    for (auto& Part : Parts)
    {
    
    
        Part.ReplaceInline(TEXT("?"), *SlashedRelativePath);
        FPaths::CollapseRelativeDirectories(Part);
        if (FPaths::IsRelative(Part))
            FullPath = FPaths::ConvertRelativePathToFull(GLuaSrcFullPath, Part);
        else
            FullPath = Part;
        if (FFileHelper::LoadFileToArray(Data, *FullPath, FILEREAD_Silent))
            return true;
    }
    return false;
}
void ULuaFileLoader::SetupCustomLoader(int Index)
{
    
    
    switch (Index)
    {
    
    
    case 0:
        FUnLuaDelegates::CustomLoadLuaFile.Unbind();
        break;
    case 1:
        FUnLuaDelegates::CustomLoadLuaFile.BindStatic(CustomLoader1);
        break;
    case 2:
        FUnLuaDelegates::CustomLoadLuaFile.BindStatic(CustomLoader2);
        break;
    }
}

Lua内置文件的加载代码,都可以在官方demo中找到,上述两个文件代码,都可以找到。

如何重写C++函数

利用的是蓝图反射的方式
注意,Unlua不支持传入参数地址的方式来传输数据,只能通过返回值
下面代码中,并不能通过TarStr来获取处理完成的数据,只能通过return数据来获取数据
(别问我怎么知道的
在这里插入图片描述
也可能不对,毕竟只是俺使用的时候遇到了这个问题,其他人俺也不知道

//Unlua Json脚本
	UFUNCTION(BlueprintImplementableEvent, BlueprintCallable)
		FString AnalysisLuaJson(const FString& OrcData, FString& TarStr);

如何在Unlua脚本中重写C++函数

如何绑定unlua脚本官方教程也有,粘吧粘吧就能用,不多讲了
我在lua文件中创建了新的函数,与C++定义的函数名和传入参数相同,以此来覆写C++函数。

function M:AnalysisLuaJson(OrcStr,TarStr)
    TarStr = AnylysisFunction.AnalysisJson(OrcStr)
    return TarStr
end

如何调用外部lua文件

function M:ReceiveBeginPlay()
	//设置lua文件路径
    package.path = "D:/UnluaScript/?.lua"
    //调用之前写的函数
    UE.ULuaFileLoader.SetupCustomLoader(2)
    --Screen.Print(string.format("FromCustomLoader2:%s", require("Analysis")))
    //AnylysisFunction指向文件,Analysis给文件命名
    AnylysisFunction=require("Analysis")
    UE.ULuaFileLoader.SetupCustomLoader(0)
    //下面这一行非常重要,是个大坑,一定要重写父项的beginplay
    self.Overridden.ReceiveBeginPlay(self)
end

外置lua脚本中的内容截图
在这里插入图片描述

//函数为需要调用的外部lua脚本中的函数
function M.AnalysisJson(OrcStr)

再把这段代码拿下来

function M:AnalysisLuaJson(OrcStr,TarStr)
	//AnalysisJson为Analysis.lua中的函数
    TarStr = AnylysisFunction.AnalysisJson(OrcStr)
    return TarStr
end

完整内置lua脚本代码

local Screen = require "Screen"
local json = require("json")
local M = UnLua.Class()
function M:ReceiveBeginPlay()
    package.path = "D:/UnluaScript/?.lua"
    UE.ULuaFileLoader.SetupCustomLoader(2)
    AnylysisFunction=require("Analysis")
    UE.ULuaFileLoader.SetupCustomLoader(0)
    self.Overridden.ReceiveBeginPlay(self)
end
function M:AnalysisLuaJson(OrcStr,TarStr)

    TarStr = AnylysisFunction.AnalysisJson(OrcStr)
    return TarStr
end
return M

已经完成了,lua的外置脚本的使用。
大菜已经上完了,下面是饭后甜点,在lua中json的读写

如何在lua中读写Json

直接上代码

//OrcStr为传入的json数据
function M.AnalysisJson(OrcStr)
    local TarStr
    //json decode
    local DecodedStr = json.decode(OrcStr)
    local AllData={
    
    }
    E1Data["pNum"]=DecodedStr.pNum
    E1Data["PData"]={
    
    }
    if DecodedStr.pNum>0 then
        for i, v in ipairs(DecodedStr.PData) do
            local data= {
    
    }
            data["id"]=v.id
            data["Name"]=v.Name
            E1Data["PData"][i]=data
        end
    end
     //json encode
    TarStr=json.encode(AllData)
    return TarStr
end

就到这了,有问题可以联系

其实写这篇文章距离我使用unlua脚本已经过去了差不多两个月了,只能说简单记录了一下过程
用的不深,有问题可以交流,太难的有可能不会,主要是总结了一下用法
qq:1264271710

猜你喜欢

转载自blog.csdn.net/qq_35410135/article/details/129525001