【UnLua】Super继承和override-创新互联
【UnLua】Super 继承和 override
新闻名称:【UnLua】Super继承和override-创新互联
文章分享:http://cdiso.cn/article/depgsc.html
这里一共有三部分
网站建设哪家好,找成都创新互联!专注于网页设计、网站建设、微信开发、小程序设计、集团企业网站建设等服务项目。为回馈新老客户创新互联还提供了屏边免费建站欢迎大家使用!- UE 本身的继承机制,包括 C++,蓝图
- UnLua 实现的 UClass 绑定机制,Super 和 Overridden 机制
- Lua 的 继承机制
提一下,因为有坑
接下来用 C++ 伪代码表示 蓝图代码
一种常见情形,就是我基类BP_A
绑定了 Lua 去覆写逻辑,然后蓝图类派生了其他类,比如 DataOnly 蓝图只配置数据不写逻辑,最后场景里只扔了派生类BP_C
实例
这里有一点切记
有一点需要注意,BP_C和BP_B的GetModuleName不能有实现,不然modulename就会变成“长度为0”的字符串了,那肯定不会调到
class BP_A : UnLuaInterface {GetModuleName =>"BP_A"; }
class BP_B : BP_A {GetModuleName =>""; } // 派生,没绑Lua
class BP_C_DataOnly : BP_B {GetModuleName =>""; } // 派生,没绑Lua
UE5 里 在 BP_C 里双击 GetModuleName 就会实现 GetModuleName
然后变成这样,蓝图会有 * ,代表修改了,非常坑爹
Lua 继承也提一下,但是纯Lua 的 OOP 实现是一个经典问题,在此不再复述
如果 BP_B 也要用 Lua 覆写,那么 Lua 里也要继承一下
有一个关键理解,就是 UnLua 并不是给所有 UClass 都找到对应的 Lua Class 去绑定,也不是 Lua Class 构造一个 UClass 去继承被覆写的蓝图类的 UClass,而是:
- 运行时监听 UObject BP_B_Obj 创建
- ModuleLocator =>GetModuleName =>require LuaModule ”BP_A.lua" //<= Note Here
- Bind UClass BP_B,把 UFunction 覆写掉,UFunctiuon->Invoke 以后都会走 Lua 实现 // BindClass 会缓存,每个 Class 只绑定一次
- Bind UObject BP_B_Obj,创建一个 Lua 对象,也就是
self
// BindObject,每个 Object 绑定一次,销毁 UObject 时销毁 LuaObject,不销毁 UClass
如果不希望 BP_B 绑定 Lua,步骤2 会返回 “BP_A.lua”
如果希望 BP_B 绑定 Lua,步骤2 会返回 “BP_B.lua”,而 BP_B LuaClass 在 Lua 中继承了 BP_A LuaClass
---@class BP_A
local M = UnLua.Class()
-- ...
---@class BP_B
local M = UnLua.Class("BP_A")
-- ...
代码实例ALS_Base_CharacterBP_C
基类ALS_AnimMan_CharacterBP_C
派生类
---@type ALS_AnimMan_CharacterBP_C
local M = UnLua.Class("Game.AdvancedLocomotionV4.Blueprints.CharacterLogic.ALS_Base_CharacterBP") -- 继承 Lua 基类
function M:GetRollAnimation()
print("GetRollAnimation")
self.Super.GetRollAnimation(self) -- 只会调用 Lua 基类实现,Lua 基类没有实现 则 self.Super.GetRollAnimation is nil
self.Overridden.GetRollAnimation(self) -- 调用 派生类蓝图实现,Lua实现 覆写了 蓝图实现,蓝图的函数指针存在 self.Overridden 里
local ReturnValue
ReturnValue = nil
return ReturnValue
end
return M
---@type ALS_Base_CharacterBP_C
local M = UnLua.Class()
function M:GetRollAnimation()
print("GetRollAnimation")
-- 基类 没有 Super
self.Overridden.GetRollAnimation(self) -- 派生类实例,Lua 基类里 self.Overridden 还是会调用 派生类蓝图 实现,不符合用意,这么用是错的
local ReturnValue
ReturnValue = nil
return ReturnValue
end
return M
结论- Lua 中
- self.Super 调用 Lua 基类实现
- self.Overridden 调用 蓝图被覆写的实现
- 蓝图中
- 蓝图节点Super调用直接跑基类蓝图实现,不跑Lua实现
- 大部分情况下的安全做法
- 不搞复杂的继承机制,即 C++ OOP 那一套 virtual override
- 只在蓝图类继承树的叶子节点绑定 Lua,写逻辑,可以通过 self.Overridden 调用 蓝图实现
- 在蓝图里使用Super节点,能调用到蓝图/C++任意层级的实现
- 两层继承
- Lua 中, 派生类 要继承 基类
- 派生类 self.Super 能调用到基类 Lua 实现
- 基类 self.Super is nil,并不会指向蓝图基类
- 基类 Lua 实现中也不能有 self.Overriden,只会调用到派生类 蓝图实现
- 三层以上继承
- 建议写纯 Lua,不要和蓝图混合编程,难以调试,容易出错
- 不要用 self.Super.Foo,用 M.Foo,确定性地调用某个 Lua 类的实现
你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧
新闻名称:【UnLua】Super继承和override-创新互联
文章分享:http://cdiso.cn/article/depgsc.html