【UnLua】ModuleLocator改造-创新互联
看起来简单的东西,UnLua 做的不是很完备,实际项目使用时藏了一些坑,之前没怎么上心,断断续续改,总还是有问题 ,今天彻底解决这个问题
创新互联自2013年创立以来,是专业互联网技术服务公司,拥有项目成都网站设计、成都网站建设网站策划,项目实施与项目整合能力。我们以让每一个梦想脱颖而出为使命,1280元栖霞做网站,已为上家服务,为栖霞各地企业和个人服务,联系电话:13518219792Module Locator 是什么Lua 接入引擎后一般需要 C++ 重写 require
- 比如调用引擎的资源管理器去加载 Lua 脚本文件(可以加密,压缩)
- 比如定制文件路径 resolve 规则(可以 fallback 查找)
UnLua 提供了一个基类ULuaModuleLocator
,有Locate
接口返回 Lua 路径
UCLASS()
class UNLUA_API ULuaModuleLocator : public UObject
{GENERATED_BODY()
public:
// 定位 Object 对应的 Lua 文件路径
virtual FString Locate(const UObject* Object);
};
默认实现长这样,返回UObject->Class->CDO->GetModuleName()
,即一个 Object 的 UClass 实现了 UnLuaInterface,就绑定了Lua,运行时会去加载GetModuleName
返回的 Lua 文件路径
FString ULuaModuleLocator::Locate(const UObject* Object)
{const UObject* CDO;
if (Object->HasAnyFlags(RF_ClassDefaultObject | RF_ArchetypeObject))
{CDO = Object;
}
else
{const auto Class = Cast(Object);
CDO = Class ? Class->GetDefaultObject() : Object->GetClass()->GetDefaultObject();
}
if (CDO->HasAnyFlags(RF_NeedInitialization))
{// CDO还没有初始化完成
return "";
}
if (!CDO->GetClass()->ImplementsInterface(UUnLuaInterface::StaticClass()))
{return "";
}
return IUnLuaInterface::Execute_GetModuleName(CDO);
}
LyraWithUnLua Demo 里提供了一个实现ULyraLuaModuleLocator
,核心是蓝图类使用蓝图资源路径,自动生成 Lua 路径
// 2. if this is blueprint, fallback to generate name by asset path
// NOTE will try to remove prefix W_, UI_, GA_
if (ModuleName.IsEmpty() && !Class->IsNative() && !CheckSuperModuleName())
{// 蓝图类使用资源路径
ModuleName = Class->GetPackage()->GetName();
ModuleName = ModuleName.Replace(TEXT("/"), TEXT("."));
TArrayParts;
ModuleName.ParseIntoArray(Parts, TEXT("."));
if (Parts.Num() >0)
{auto& LastPart = Parts[Parts.Num() - 1];
int32 Index = 0;
if (LastPart.FindChar('_', Index) && Index< 4)
{ LastPart.RightChopInline(Index + 1);
}
ModuleName = FString::Join(Parts, TEXT("."));
}
}
问题ULyraLuaModuleLocator
一开始很方便,但是这个接口设计犯了一个错,就是一个接口干了两个接口的活,导致用这个接口怎么也干不好,参考realloc
,同时干malloc
和free
两件事
ULyraLuaModuleLocator
的问题在于,蓝图类构造了继承链之后
这里用 C++ 代表 蓝图代码
在基类上绑定 Lua,预期是只有基类绑定了 Lua,但是实际是派生类 也自动绑定了 Lua,运行时会找不到 Lua 文件,然后报错
class BP_A : UnLuaInterface {GetModuleName =>"BP_A"; }
class BP_B : BP_A {GetModuleName =>""; } // 派生,没绑Lua
class BP_C_DataOnly : BP_B {GetModuleName =>""; } // 派生,没绑Lua
class BP_A : UnLuaInterface {GetModuleName =>"BP_A";
virtual
}
class BP_B : BP_A {GetModuleName =>""; } // 派生,没绑Lua
class BP_C_DataOnly : BP_B {GetModuleName =>""; } // 派生,没绑Lua
解决分两个接口来做
- 额外加一个按钮自动填充 GetModuleName 路径,使用
ULyraLuaModuleLocator
,只有这个按钮会走这里 - 运行时,编辑器跑
ULuaModuleLocator
,简单,稳定,快速
【UnLua】Super 继承和 override_zoloypzuo的博客-博客
这篇文章中,我们仔细讨论了继承的情况,建议阅读,两篇文章有关联
小结主要是编程上的注意
- 分离 Editor 和 Runtime 行为
- 一个接口只做一件事,不要同时负责写入+读取
- Runtime 行为保持简单,确定性,不要有潜规则,难以调试,容易隐藏问题
你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧
网站名称:【UnLua】ModuleLocator改造-创新互联
网页网址:http://ybzwz.com/article/cdsiso.html