UnLua使用指引【第二篇】UE静态导出与UE调用lua

上一篇讲的lua调用UE主要都是通过UE的反射系统来进行调用,UnLua还提供了一些简单的方法导出没有反射的类和函数,及成员。

开头提出一个问题(为什么UnLua已经可以直接通过反射系统调用C++,还需要类导出呢)

结尾解答

 

目录

静态导出

导出成员变量

导出成员函数

导出全局函数

引擎调用Lua

蓝图函数重载

UE输入重载(包括动作和轴输入)

C++中调用Lua函数

总结


静态导出

类 

  • Non-reflected classes
BEGIN_EXPORT_CLASS(ClassType, ...)

Or

BEGIN_EXPORT_NAMED_CLASS(ClassName, ClassType, ...)

'...' 是构造函数的类型列表,


  • Non-reflected classes
BEGIN_EXPORT_CLASS(ClassType, ...)

Or

BEGIN_EXPORT_NAMED_CLASS(ClassName, ClassType, ...)

'...'是构造函数的类型列表,


导出成员变量

ADD_PROPERTY(Property)

Or (for bitfield bool property)

ADD_BITFIELD_BOOL_PROPERTY(Property)

导出成员函数

  • 紧凑风格
ADD_FUNCTION(Function)

Or

ADD_NAMED_FUNCTION(Name, Function)
  • 完整版本
ADD_FUNCTION_EX(Name, RetType, Function, ...)

Or

ADD_CONST_FUNCTION_EX(Name, RetType, Function, ...)

'...' means parameter types.

静态函数

ADD_STATIC_FUNCTION(Function)

Or

ADD_STATIC_FUNCTION_EX(Name, RetType, Function, ...)

'...' 是参数类型

Example

struct Vec3
{
	Vec3() : x(0), y(0), z(0) {}
	Vec3(float _x, float _y, float _z) : x(_x), y(_y), z(_z) {}

	void Set(const Vec3 &V) { *this = V; }
	Vec3& Get() { return *this; }
	void Get(Vec3 &V) const { V = *this; }

	bool operator==(const Vec3 &V) const { return x == V.x && y == V.y && z == V.z; }

	static Vec3 Cross(const Vec3 &A, const Vec3 &B) { return Vec3(A.y * B.z - A.z * B.y, A.z * B.x - A.x * B.z, A.x * B.y - A.y * B.x); }
	static Vec3 Multiply(const Vec3 &A, float B) { return Vec3(A.x * B, A.y * B, A.z * B); }
	static Vec3 Multiply(const Vec3 &A, const Vec3 &B) { return Vec3(A.x * B.x, A.y * B.y, A.z * B.z); }

	float x, y, z;
};

BEGIN_EXPORT_CLASS(Vec3, float, float, float)
	ADD_PROPERTY(x)
	ADD_PROPERTY(y)
	ADD_PROPERTY(z)
	ADD_FUNCTION(Set)
	ADD_NAMED_FUNCTION("Equals", operator==)
	ADD_FUNCTION_EX("Get", Vec3&, Get)
	ADD_CONST_FUNCTION_EX("GetCopy", void, Get, Vec3&)
	ADD_STATIC_FUNCTION(Cross)
	ADD_STATIC_FUNCTION_EX("MulScalar", Vec3, Multiply, const Vec3&, float)
	ADD_STATIC_FUNCTION_EX("MulVec", Vec3, Multiply, const Vec3&, const Vec3&)
END_EXPORT_CLASS()
IMPLEMENT_EXPORTED_CLASS(Vec3)

导出全局函数

XPORT_FUNCTION(RetType, Function, ...)

Or

EXPORT_FUNCTION_EX(Name, RetType, Function, ...)

'...' means parameter types.

导出枚举:

  • Unscoped enumeration 无域化
enum EHand
{
	LeftHand,
	RightHand
};

BEGIN_EXPORT_ENUM(EHand)
	ADD_ENUM_VALUE(LeftHand)
	ADD_ENUM_VALUE(RightHand)
END_EXPORT_ENUM(EHand)
  • Scoped enumeration 域化
enum class EEye
{
	LeftEye,
	RightEye
};

BEGIN_EXPORT_ENUM(EEye)
	ADD_SCOPED_ENUM_VALUE(LeftEye)
	ADD_SCOPED_ENUM_VALUE(RightEye)
END_EXPORT_ENUM(EEye)

域化的区别在于复制的时候必须要加上枚举域 如EEye:LeftEye


引擎调用Lua

Unlua提供了类似蓝图的方法,可以让C++或者蓝图调用lua中的函数

蓝图函数重载

蓝图函数包括

  • BlueprintImplementableEvent/BlueprintNativeEvent 标记的UFUNCTION
  • 蓝图中定义的事件和函数

UFUNCTION(BlueprintImplementableEvent)
void receiveBeginPlay()

可以覆盖如下

function BP_PlayerController_C:ReceiveBeginPlay()
  print("ReceiveBeginPlay in Lua!")
end

(带返回值的这里就先不写了)

UE输入重载(包括动作和轴输入)

UnLua使用指引【第二篇】UE静态导出与UE调用lua_第1张图片

Action Inputs

function BP_PlayerController_C:Aim_Pressed()
	UBPI_Interfaces_C.UpdateAiming(self.Pawn, true)
end

function BP_PlayerController_C:Aim_Released()
	UBPI_Interfaces_C.UpdateAiming(self.Pawn, false)
end

Lua函数名必须是 ActionName + '_Pressed' / '_Released'.

Axis Inputs

function BP_PlayerController_C:Turn(AxisValue)
	self:AddYawInput(AxisValue)
end

function BP_PlayerController_C:LookUp(AxisValue)
	self:AddPitchInput(AxisValue)
end

Lua函数名必须和 输入相同 AxisName.

Key Inputs

function BP_PlayerController_C:P_Pressed()
	print("P_Pressed")
end

function BP_PlayerController_C:P_Released()
	print("P_Released")
end

lua函数名必须是 KeyName + '_Pressed' / '_Released'.

如果重写了蓝图函数,Lua中的override函数仍然可以调用UE本身被复写的函数

C++中调用Lua函数

UnLua还提供了两种通用方法来调用全局Lua函数和C ++代码中的全局Lua表中的函数。

  • Global functions
template 
FLuaRetValues Call(lua_State *L, const char *FuncName, T&&... Args);
  • Functions in global table
template 
FLuaRetValues CallTableFunc(lua_State *L, const char *TableName, const char *FuncName, T&&... Args);

总结

  本篇内容主要包含

  • C++中的静态导出,lua可以调用导出的类,函数,成员
  • UE调用Lua,主要通过
    • 复写蓝图函数(函数名要求
    • 动作/轴输入(函数名要求
  • C++调用Lua还可以直接调用Lua的全局函数和在lua全局表中的函数。

刚刚去问了老师,原来是因为有些函数不是UFUNCTIO,没法直接调用,需要被ADD_FUNCTION导出,但是导出需要先导出类再导出函数,因此UCLASS也需要被静态导出

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