UnLua使用指引【第一篇】Unlua绑定UE 以及Lua调用

OverView

UnLua是针对UE4的功能丰富且经过高度优化的脚本解决方案。 开发人员可以使用Lua来开发游戏逻辑,并且可以使用Lua的热加载功能更快地迭代游戏逻辑。 本文档将介绍UnLua的主要功能和基本编程模式。


Lua&UE 绑定

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的相对路径

这里的实践使用暂时还没见过。

Lua调用引擎

UnLua提供了两种从Lua一侧访问引擎的方法:1.使用反射系统动态导出; 2.在反射系统之外静态导出类,成员变量,成员函数,全局函数和枚举。

使用反射系统导出可以使代码干净,直观,并且可以消除大量胶水代码。

获取UCLASS

local Widget = UWidgetBlueprintLibrary.Create(self, UClass.Load("/Game/Core/UI/UMG_Main"))

UWidgetBlueprintLibrary 是一个UCLASS,Lua中的类名字必须是PrefixCPP(类前缀加类型,如果是AActor,蓝图类,那么就是ABP,个人理解)+类名字+【_c】

获取UFUNCTION

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调用进行了一下几点优化

  • 永恒的参数buffer
  • 优化局部函数调用
  • 优化函数传递
  • 优化输出值处理

lua获取USTRUCT

local Position = FVector()

FVector是一个USTRUCT

获取UPROPERTY

local Position = FVector()
Position.X = 256.0

X就是FVector的一个UPROPERTY

Delegates(可以以通用的类型安全的方式在C ++对象上调用成员函数。 委托可以动态绑定到任意对象的成员函数,即使将来调用者不知道该对象的类型,也可以在将来对其进行调用。)

将Lua函数绑定到一个delegate上去

FloatTrack.InterpFunc:Bind(self, BP_PlayerCharacter_C.OnZoomInOutUpdate)

获取UENUM

在函数调用的时候直接通过“.”获取枚举即可

如果要增加新的枚举值

local ObjectTypes = TArray(EObjectTypeQuery)
ObjectTypes:Add(EObjectTypeQuery.Player)
ObjectTypes:Add(EObjectTypeQuery.Enemy)
ObjectTypes:Add(EObjectTypeQuery.Projectile)

先将枚举用数组获取,再调用add添加


手动导出库

  出于性能考虑,Unlua手动导出了引擎库

Basic Classes

  • UObject
  • UClass
  • UWorld

Common Containers

  • TArray
  • TSet
  • TMap
	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

  • FVector
  • FVector2D
  • FVector4
  • FQuat
  • FRotator
  • FTransform
  • FColor
  • FLinearColor
  • FIntPoint
  • FIntVector

总结

  • 关于绑定,unlua提供了两种绑定,一种是通过复写unlua的getmodulename接口,还有一种动态绑定是在动态生成actor时和object时调用。
  • 关于调用lua调用引擎(通过反射系统动态导出
    • 调用UCLASS:直接通过反射来进行调用
    • 调用UFUNCTION,USTRUCT,ENUM,UPROPERTY 只要在C++里被标记了的就可以直接调用
    • 关于非常量引用参数,返回参数的执行方法
    • 潜在功能(有待实践
    • 执行Delegates(和onclicked绑定时类似的,不过只能绑定一个事件,是在蓝图里的delegate绑定了Lua里的回调函数)
  • Unlua导出了一些通用库和类,可以直接在lua中调用(需要拿到全局的这些变量

你可能感兴趣的:(腾讯客户端Gameplay)