赞
踩
@UE5使用外置Unlua脚本
git地址,里面有很多demo,可以去看,下面所述是我工作中所使用的一部分,重写C++函数和加载外置脚本。
https://github.com/Tencent/UnLua
我使用的是vs code的lua Booster
简单讲解一下使用方法
首先需要将待调试的ue程序启动
点击run and debug
选择第一个
之后选择待调试的项目
等待加载一段时间,即可进行调试
hooker ready 表示加载完成
首先定义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中找到,上述两个文件代码,都可以找到。
利用的是蓝图反射的方式
注意,Unlua不支持传入参数地址的方式来传输数据,只能通过返回值
下面代码中,并不能通过TarStr来获取处理完成的数据,只能通过return数据来获取数据
(别问我怎么知道的
也可能不对,毕竟只是俺使用的时候遇到了这个问题,其他人俺也不知道
)
//Unlua Json脚本
UFUNCTION(BlueprintImplementableEvent, BlueprintCallable)
FString AnalysisLuaJson(const FString& OrcData, FString& TarStr);
如何绑定unlua脚本官方教程也有,粘吧粘吧就能用,不多讲了
我在lua文件中创建了新的函数,与C++定义的函数名和传入参数相同,以此来覆写C++函数。
function M:AnalysisLuaJson(OrcStr,TarStr)
TarStr = AnylysisFunction.AnalysisJson(OrcStr)
return TarStr
end
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的读写
直接上代码
//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
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。