上一篇讲的lua调用UE主要都是通过UE的反射系统来进行调用,UnLua还提供了一些简单的方法导出没有反射的类和函数,及成员。
开头提出一个问题(为什么UnLua已经可以直接通过反射系统调用C++,还需要类导出呢)
结尾解答
目录
静态导出
类
导出成员变量
导出成员函数
导出全局函数
引擎调用Lua
蓝图函数重载
UE输入重载(包括动作和轴输入)
C++中调用Lua函数
总结
BEGIN_EXPORT_CLASS(ClassType, ...)
Or
BEGIN_EXPORT_NAMED_CLASS(ClassName, ClassType, ...)
'...' 是构造函数的类型列表,
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.
导出枚举:
enum EHand
{
LeftHand,
RightHand
};
BEGIN_EXPORT_ENUM(EHand)
ADD_ENUM_VALUE(LeftHand)
ADD_ENUM_VALUE(RightHand)
END_EXPORT_ENUM(EHand)
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
Unlua提供了类似蓝图的方法,可以让C++或者蓝图调用lua中的函数
蓝图函数包括
如
UFUNCTION(BlueprintImplementableEvent)
void receiveBeginPlay()
可以覆盖如下
function BP_PlayerController_C:ReceiveBeginPlay()
print("ReceiveBeginPlay in Lua!")
end
(带返回值的这里就先不写了)
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本身被复写的函数
UnLua还提供了两种通用方法来调用全局Lua函数和C ++代码中的全局Lua表中的函数。
template
FLuaRetValues Call(lua_State *L, const char *FuncName, T&&... Args);
template
FLuaRetValues CallTableFunc(lua_State *L, const char *TableName, const char *FuncName, T&&... Args);
本篇内容主要包含
刚刚去问了老师,原来是因为有些函数不是UFUNCTIO,没法直接调用,需要被ADD_FUNCTION导出,但是导出需要先导出类再导出函数,因此UCLASS也需要被静态导出