UnLua是针对UE4的功能丰富且经过高度优化的脚本解决方案。 开发人员可以使用Lua来开发游戏逻辑,并且可以使用Lua的热加载功能更快地迭代游戏逻辑。 本文档将介绍UnLua的主要功能和基本编程模式。
Unlua提供了两种绑定方式,静态绑定和自定义绑定。
如果是C++里,类里面需要实现Unlua接口,写一个函数GetModuleName_Implementation,函数返回返回一个Lua文件路径
蓝图里就直接在类设置里添加Unlua接口,会自动添加GetModuleName接口,在里面填写lua文件名字即可。(文件前有时需要写对应的路径)
自定义绑定适用于实时生成Actor和对象
比如说
local Proj = World:SpawnActor(ProjClass, Transform, ESpawnActorCollisionHandlingMethod.AlwaysSpawn, self, self.Instigator, "Weapon.BP_DefaultProjectile_C")
“Weapon.BP_DefaultProjectile_C” 是一个lua文件路径。
local ProxyObj = NewObject(ObjClass, nil, nil, "Objects.ProxyObject")
“Objects.ProxyObject”也是一个lua文件路径
Lua文件路径都是相对于Content/Scripts的相对路径
这里的实践使用暂时还没见过。
UnLua提供了两种从Lua一侧访问引擎的方法:1.使用反射系统动态导出; 2.在反射系统之外静态导出类,成员变量,成员函数,全局函数和枚举。
使用反射系统导出可以使代码干净,直观,并且可以消除大量胶水代码。
local Widget = UWidgetBlueprintLibrary.Create(self, UClass.Load("/Game/Core/UI/UMG_Main"))
UWidgetBlueprintLibrary 是一个UCLASS,Lua中的类名字必须是PrefixCPP(类前缀加类型,如果是AActor,蓝图类,那么就是ABP,个人理解)+类名字+【_c】
Widget:AddToViewport(0)
如果UFUNCTION(有标签 'BlueprintCallable' or 'Exec'),有一个默认参数,那么在lua中可以不写这个默认参数。
返回值处理:返回值包括非常量引用和返回参数。这些值都可以分为原生类型(比如int bool string)和非原生类型(UE的自定义结构体。如下图
UFUNCTION()
void GetPlayerBaseInfo(int 32 &level,float &Health,FString &Name) const;
对于非常量引用的原生类型调用:Lua代码如下
local Level, Health, Name = self:GetPlayerBaseInfo()
对于非原生类型比如:
UFUNCTION()
void GetHitResult(FHitResult) const;
lua里有两种调用方法
local HitResult = FHitResult()
self:GetHitResult(HitResult)
或者
local HitResult = self:GetHitResult()
第一个调用函数有点类似于C++,如果多次调用,第一个函数比第二个函数会高效率很多
对于返回参数的调用(原生类型)如下
UFUNCTION()
float GetMeleeDamage() const;
原生类型lua代码调用如下
local MeleeDamage = self:GetMeleeDamage()
非原生类型
UFUNCTION()
FVector GetCurrentLocation() const
lua有三种调用方式
local Location = self:GetCurrentLocation()
Or
local Location = FVector()
self:GetCurrentLocation(Location)
Or
local Location = FVector()
local LocationCopy = self:GetCurrentLocation(Location)
第一个最直观,但是后面两个调用方式效率更高。
潜在功能
潜在功能允许开发者使用同步调用风格去调用异步逻辑。一个典型的潜在功能就是Delay
转存失败重新上传取消我们可以在lua协程里调用delay函数
coroutine.resume(coroutine.create(function(GameMode, Duration) UKismetSystemLibrary.Delay(GameMode, Duration) end), self, 5.0)
(这里的实践在代码中还未见过,待补充)
Unlua对UFUNCTION调用进行了一下几点优化
local Position = FVector()
FVector是一个USTRUCT
local Position = FVector()
Position.X = 256.0
X就是FVector的一个UPROPERTY
将Lua函数绑定到一个delegate上去
FloatTrack.InterpFunc:Bind(self, BP_PlayerCharacter_C.OnZoomInOutUpdate)
在函数调用的时候直接通过“.”获取枚举即可
如果要增加新的枚举值
local ObjectTypes = TArray(EObjectTypeQuery)
ObjectTypes:Add(EObjectTypeQuery.Player)
ObjectTypes:Add(EObjectTypeQuery.Enemy)
ObjectTypes:Add(EObjectTypeQuery.Projectile)
先将枚举用数组获取,再调用add添加
出于性能考虑,Unlua手动导出了引擎库
Basic Classes
Common Containers
local Indices = TArray(0)
Indices:Add(1)
Indices:Add(3)
Indices:Remove(0)
local NbIndices = Indices:Length()
local Vertices = TArray(FVector)
local Actors = TArray(AActor)
Math Libraries