当前位置:   article > 正文

UE5使用外置Unlua脚本_ue5界面绑定lua

ue5界面绑定lua

@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);
};

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

.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;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55

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

如何重写C++函数

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

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

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

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

function M:AnalysisLuaJson(OrcStr,TarStr)
    TarStr = AnylysisFunction.AnalysisJson(OrcStr)
    return TarStr
end
  • 1
  • 2
  • 3
  • 4

如何调用外部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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

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

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

再把这段代码拿下来

function M:AnalysisLuaJson(OrcStr,TarStr)
	//AnalysisJson为Analysis.lua中的函数
    TarStr = AnylysisFunction.AnalysisJson(OrcStr)
    return TarStr
end
  • 1
  • 2
  • 3
  • 4
  • 5

完整内置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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

已经完成了,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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

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

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

声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:【wpsshop博客】
推荐阅读
  

闽ICP备14008679号