# UnLua **Repository Path**: haze347/UnLua ## Basic Information - **Project Name**: UnLua - **Description**: No description available - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-05-31 - **Last Updated**: 2026-08-10 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ![LOGO](./Docs/Images/UnLua.png) [![license](https://img.shields.io/badge/license-MIT-blue)](https://github.com/Tencent/UnLua/blob/master/LICENSE.TXT) [![release](https://img.shields.io/github/v/release/Tencent/UnLua)](https://github.com/Tencent/UnLua/releases) [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](https://github.com/Tencent/UnLua/pulls) # 概述 **UnLua**是适用于UE的一个高度优化的**Lua脚本解决方案**。它遵循UE的编程模式,功能丰富且易于学习,UE程序员可以零学习成本使用。 # 在UE中使用Lua * 直接访问所有的UCLASS, UPROPERTY, UFUNCTION, USTRUCT, UENUM,无须胶水代码。 * 替换蓝图中定义的实现 ( Event / Function )。 * 处理各类事件通知 ( Replication / Animation / Input )。 更详细的功能介绍请查看[功能清单](Docs/CN/Features.md)。 # 优化特性 * UFUNCTION调用,包括持久化参数缓存、优化的参数传递、优化的非常量引用和返回值处理。 * 访问容器类(TArray, TSet, TMap),内存布局与引擎一致,Lua Table和容器之间不需要转换。 * 高效的结构体创建、访问、GC。 * 支持自定义静态导出类、成员变量、成员函数、全局函数、枚举。 # 平台支持 * 运行平台:Windows / Android / iOS / Linux / OSX * 引擎版本:Unreal Engine 4.17.x - Unreal Engine 5.x **注意**: 4.17.x 和 4.18.x 版本需要对 Build.cs 做一些修改。 # 快速开始 ## 安装 1. 复制 `Plugins` 目录到你的UE工程根目录。 2. 重新启动你的UE工程 ## 开始UnLua之旅 **注意**: 如果你是一位UE萌新,推荐使用更详细的[图文版教学](Docs/CN/Quickstart_For_UE_Newbie.md)继续以下步骤。 1. 新建蓝图后打开,在UnLua工具栏中选择 `绑定`(可同时按住`Alt`键自动生成第2步的路径) 2. 在接口的 `GetModule` 函数中填入Lua文件路径,如 `GameModes.BP_MyGameMode` 3. 选择UnLua工具栏中的 `创建Lua模版文件` 4. 打开 `Content/Script/GameModes/BP_MyGameMode.lua` 编写你的代码 # 更多示例 * [01_HelloWorld](Content/Script/Tutorials/01_HelloWorld.lua) 快速开始的例子 * [02_OverrideBlueprintEvents](Content/Script/Tutorials/02_OverrideBlueprintEvents.lua) 覆盖蓝图事件(Overridden Functions) * [03_BindInputs](Content/Script/Tutorials/03_BindInputs.lua) 输入事件绑定 * [04_DynamicBinding](Content/Script/Tutorials/04_DynamicBinding.lua) 动态绑定 * [05_BindDelegates](Content/Script/Tutorials/05_BindDelegates.lua) 委托的绑定、解绑、触发 * [06_NativeContainers](Content/Script/Tutorials/06_NativeContainers.lua) 引擎层原生容器访问 * [07_CallLatentFunction](Content/Script/Tutorials/07_CallLatentFunction.lua) 在协程中调用 `Latent` 函数 * [08_CppCallLua](Content/Script/Tutorials/08_CppCallLua.lua) 从C++调用Lua * [09_StaticExport](Content/Script/Tutorials/09_StaticExport.lua) 静态导出自定义类型到Lua使用 * [10_Replications](Content/Script/Tutorials/10_Replications.lua) 覆盖网络复制事件 * [11_ReleaseUMG](Content/Script/Tutorials/11_ReleaseUMG.lua) 释放UMG相关对象 * [12_CustomLoader](Content/Script/Tutorials/12_CustomLoader.lua) 自定义加载器 * [13_AnimNotify](Content/Script/Tutorials/AN_FootStep.lua) 动画通知 # 最佳实践示例 [Lyra with UnLua](https://github.com/xuyanghuang-tencent/LyraWithUnLua) 基于UE官方 **Lyra初学者游戏包** 的完整示例项目,目前正在施工中 # 文档 常用文档:[设置选项](Docs/CN/Settings.md) | [调试](Docs/CN/Debugging.md) | [智能提示](Docs/CN/IntelliSense.md) | [控制台命令](Docs/CN/ConsoleCommand.md) | [FAQ](Docs/CN/FAQ.md) 详细介绍: * [编程指南](Docs/CN/UnLua_Programming_Guide.md):介绍 UnLua 的主要功能和编程模式 * [插件与模块](Docs/CN/Plugins_And_Modules.md):介绍 Plugins 目录下的插件列表以及它们所包含的模块 * [功能清单](Docs/CN/Features.md):更详细的功能列表 * [实现原理](Docs/CN/How_To_Implement_Overriding.md):介绍 UnLua 的两种覆盖机制 * [API](Docs/CN/API.md):更详细的 UnLua API 说明 # 技术支持 - 官方交流QQ群:936285107 - 推荐VSCode插件:[Lua Booster](https://marketplace.visualstudio.com/items?itemName=operali.lua-booster) # UE 5.8 兼容性修改记录 本分支针对 **Unreal Engine 5.8** 做了以下兼容性调整,以保证 `P1GameEditor Win64 Development` 目标可完整编译通过: ## 1. UBT 插件升级到 .NET 10 UE 5.8 的 `EpicGames.UHT` 等程序集已迁移到 `.NET 10`,因此 `UnLuaDefaultParamCollectorUbtPlugin.ubtplugin.csproj` 需要同步升级: - `` 从 `net6.0` 改为 `net10.0`。 - 移除 ``,避免 `NU1510` 错误。 - 该 `.csproj` 通过 `$(EngineDir)` 引用引擎共享的 `UnrealEngine.csproj.props`,因此需要同目录下的 `UnLuaDefaultParamCollectorUbtPlugin.ubtplugin.csproj.props` 来定义 `EngineDir`。该 props 文件包含本机绝对路径,已加入 `.gitignore`,不参与版本控制,每个开发者首次构建前需按本地 UE 路径创建。 ## 2. UHT API 适配 UE 5.8 的 UHT 中 `UhtSession` 不再暴露 `Packages` 属性,包的访问方式改为按模块组织: - `UnLuaDefaultParamCollectorUbtPlugin.cs` 中的 `Generate()` 方法改为遍历 `Session.Modules`。 - 模块类型、名称、输出目录统一通过 `module.Module` 获取。 - 每个模块下的包通过 `module.Packages` 遍历。 ## 3. 多播委托调用修复 UE 5.8 中 `TMulticastScriptDelegate::ProcessDelegate` 需要显式模板参数 `UObject`: - `Source/UnLua/Private/ReflectionUtils/FunctionDesc.cpp` 中的 `BroadcastMulticastDelegate` 已改为 `ScriptDelegate->ProcessDelegate(Params);`。 另外,`CallLua` 中原本通过 `Function->ChildProperties` 链表遍历函数参数,在 UE 5.8 下不再适用,已改为使用 `TFieldIterator` 迭代,并跳过返回值参数 `CPF_ReturnParm`。 ## 4. LuaRapidjson 编译符号遮蔽修复 UE 5.8 默认启用更严格的 shadow variable 检查,`rapidjson::SizeType` 会遮蔽引擎 `TArray` 内部的 `SizeType`,导致 `C4459` 错误: - `LuaRapidjson.Build.cs` 中调整编译警告设置: - `PCHUsage` 改为 `NoPCHs`,避免共享 PCH 的警告策略覆盖模块设置。 - `bEnableUndefinedIdentifierWarnings = false` 改为 `CppCompileWarningSettings.UndefinedIdentifierWarningLevel = WarningLevel.Off`。 - 新增 `CppCompileWarningSettings.ShadowVariableWarningLevel = WarningLevel.Off`。 - `Source/src/values.cpp` 中移除 `using rapidjson::SizeType;`,显式使用 `rapidjson::SizeType`。 - `rapidjson.cpp`、`Document.cpp`、`Schema.cpp` 顶部增加 `#pragma warning(disable : 4459)` 以隔离第三方头文件影响。 ## 5. 属性构造 API 适配(UE 5.7+) UE 5.7 起,`FBoolProperty`、`FIntProperty`、`FFloatProperty`、`FStrProperty`、`FNameProperty`、`FTextProperty`、`FObjectProperty`、`FStructProperty`、`FEnumProperty`、`FByteProperty` 等构造参数大幅简化,原 `RF_Transient` 等参数版本被移除: - `Source/UnLua/Private/Registries/PropertyRegistry.cpp` 中通过 `UE_VERSION_NEWER_THAN(5, 7, 0)` 分支使用新的无参构造,再手动设置 `PropertyClass` / `Struct` / `SetEnum` / `SetElementSize` / `PropertyFlags`。 - `FEnumProperty` 构造后通过 `SetEnum()` 绑定底层枚举;底层 `FByteProperty` 构造不再传递 `RF_Transient`。 - `Source/UnLua/Private/ReflectionUtils/PropertyDesc.cpp` 中数组内层属性改用 `GetElementSize()`。 - `Source/UnLua/Private/LuaCore.cpp` 中属性大小访问同样改为 `GetElementSize()`。 涉及文件: - `Source/UnLua/Private/Registries/PropertyRegistry.cpp` - `Source/UnLua/Private/ReflectionUtils/PropertyDesc.cpp` - `Source/UnLua/Private/LuaCore.cpp` ## 6. UObject / 元数据 API 迁移 UE 5.7+ 中部分 UObject 和元数据 API 发生变更: - `UMetaData::CopyMetadata` / `UMetaData::GetMapForObject` → 改用 `FMetaData::CopyMetadata` / `FMetaData::GetMapForObject`。 - 原始裸指针成员(如 `UFunction* Overridden`)→ 改用 `TObjectPtr`。 - `TSet` → 改用 `TSet>`。 - `UClass::ClassDefaultObject` 直接赋值 → 改用 `SetDefaultObject()`。 涉及文件: - `Source/UnLua/Private/LuaFunction.cpp` - `Source/UnLua/Private/ObjectReferencer.h` - `Source/UnLua/Private/LuaOverridesClass.cpp` - `Source/UnLua/Private/LuaOverrides.cpp` - `Source/UnLuaDefaultParamCollector/Private/UnLuaDefaultParamCollector.cpp` - `Source/UnLua/Public/LuaFunction.h` ## 7. Lua 函数反射结构遍历修复 UE 5.7 起 `UFunction::Children` / `ChildProperties` 等字段不再对外使用: - `Source/UnLua/Private/LuaFunction.cpp` 中 `SetActive` / `FinishDestroy` 对 `Children` / `ChildProperties` 的复制/清空操作已用 `UE_VERSION_OLDER_THAN(5, 7, 0)` 包裹。 - `Source/UnLua/Private/ReflectionUtils/FunctionDesc.cpp` 中函数参数遍历改为 `TFieldIterator`,跳过 `CPF_ReturnParm`。 - `Source/UnLua/Private/UnLuaDebugBase.cpp` 中结构体属性遍历同样改为 `TFieldIterator`。 涉及文件: - `Source/UnLua/Private/LuaFunction.cpp` - `Source/UnLua/Private/ReflectionUtils/FunctionDesc.cpp` - `Source/UnLua/Private/UnLuaDebugBase.cpp` ## 8. Lua 运行时与引擎内部类型隔离 UE 5.7 引入了全局 `TString` 类型别名,与 Lua 内部 `TString` 结构体冲突,导致 Lua 作为 C++ 编译时符号混乱: - `Source/UnLua/Private/LuaEnv.cpp` 中引入 `lstate.h` 前临时 `#define TString LuaInternalTString`,包含后 `#undef TString`。 - `Source/ThirdParty/Lua/Lua.Build.cs` 中 `ShouldCompileAsCpp()` 在 `UE_5_7_OR_LATER` 下直接返回 `false`,避免 C++ 编译路径的冲突。 - `EInternalObjectFlags::AsyncLoading` 在 5.6+ 中已移除,`LuaEnv.cpp` 中通过版本宏仅保留 `EInternalObjectFlags::Async`。 涉及文件: - `Source/UnLua/Private/LuaEnv.cpp` - `Source/ThirdParty/Lua/Lua.Build.cs` ## 9. 构建系统与模板现代化 - `Source/ThirdParty/Lua/Lua.Build.cs` 中: - 警告设置迁移到 `CppCompileWarningSettings.UndefinedIdentifierWarningLevel` / `ShadowVariableWarningLevel`。 - `WindowsCompiler.VisualStudio2019` 在 UE 5.5+ 已移除,删除对应分支。 - `Source/UnLua/Public/UnLuaTemplate.h` 中 `TChooseClass<...>` 改为 `std::conditional_t`。 - `Source/UnLua/Public/UnLuaEx.inl` / `Source/UnLua/Public/UnLuaLegacy.h` 中大量 `TChooseClass` 编译期分支改为 `if constexpr` + `std::conditional_t` / `std::is_trivially_destructible_v` 等现代 C++ 写法。 - 版本判断宏由 `UE_VERSION_NEWER_THAN(5, 2, 1)` 修正为 `UE_VERSION_NEWER_THAN(5, 2, 0)`。 - `Source/UnLua/Public/UnLuaSettings.h` 中 `MetaClass="Object"` 改为完整路径 `MetaClass="/Script/CoreUObject.Object"`。 - `DefaultParamCollection.cpp` 中对 `DefaultParamCollection.inl` 增加 `__has_include` 保护,避免首次生成前文件缺失导致编译失败。 - `LuaProtobuf` 的 `pb.h` 中 `__GNUC__` 判断改为 `defined(__GNUC__) && __GNUC__`,兼容 MSVC。 涉及文件: - `Source/ThirdParty/Lua/Lua.Build.cs` - `Source/UnLua/Public/UnLuaTemplate.h` - `Source/UnLua/Public/UnLuaEx.inl` - `Source/UnLua/Public/UnLuaLegacy.h` - `Source/UnLua/Private/LuaFunction.cpp` - `Source/UnLua/Private/Registries/PropertyRegistry.cpp` - `Source/UnLua/Public/UnLuaSettings.h` - `Source/UnLua/Private/DefaultParamCollection.cpp` - `Plugins/UnLuaExtensions/LuaProtobuf/Source/src/pb.h` ## 10. 弃用警告修复 以下 UE 5.8 已弃用 API 已全部迁移完成,当前构建无相关 `C4996` 警告: - `FProperty::ElementSize` → 改用 `GetElementSize()` / `SetElementSize()`。 - `FEnumProperty` / `FByteProperty` 带 `RF_Transient` 的构造参数 → 移除该参数。 - `UClass::ClassDefaultObject` → 改用 `SetDefaultObject()`。 - `FCoreDelegates::OnPostEngineInit` → 改用 `GetOnPostEngineInit()`。 - `ForEachObjectWithPackage` 布尔参数重载 → 改用 `EGetObjectsFlags::None` 版本。 - `FAssetData::ObjectPath` → 改用 `GetObjectPathString()`。 涉及文件: - `Source/UnLua/Private/ReflectionUtils/PropertyDesc.cpp` - `Source/UnLua/Private/Registries/PropertyRegistry.cpp` - `Source/UnLua/Private/LuaCore.cpp` - `Source/UnLua/Private/LuaOverridesClass.cpp` - `Source/UnLuaEditor/Private/UnLuaEditorModule.cpp` - `Source/UnLuaEditor/Private/UnLuaIntelliSenseGenerator.cpp` ## 11. 第三方库弃用警告抑制 LuaProtobuf、LuaSocket 等第三方源码因使用 POSIX/CRT/Winsock 传统接口(`fopen`、`setmode`、`inet_ntoa`、`gai_strerror` 等),会触发 `C4996`。由于直接改动第三方源码维护成本较高,采用工程化方式抑制: - `LuaProtobuf.Build.cs` / `LuaSocket.Build.cs` 中已添加: - `_CRT_SECURE_NO_WARNINGS` - `_CRT_NONSTDC_NO_DEPRECATE` - `_WINSOCK_DEPRECATED_NO_WARNINGS`(仅 LuaSocket) - 对应 `.cpp` 顶部增加 `#pragma warning(disable : 4996)`。 - LuaSocket 中自定义的 `gai_strerror` 宏与 Windows SDK 宏冲突,已用 `#ifdef gai_strerror / #undef gai_strerror` 处理,避免 `C4005`。 - `LuaRapidjson` 的 `LoadSynchronous` 函数指针强转触发 `C4191`,已在 `LuaLib_Object.cpp` 对应位置用 `#pragma warning(disable : 4191)` 包裹。 涉及文件: - `Plugins/UnLuaExtensions/LuaProtobuf/Source/LuaProtobuf.Build.cs` - `Plugins/UnLuaExtensions/LuaProtobuf/Source/src/pb.cpp` - `Plugins/UnLuaExtensions/LuaSocket/Source/LuaSocket.Build.cs` - `Plugins/UnLuaExtensions/LuaSocket/Source/src/auxiliar.cpp` - `Plugins/UnLuaExtensions/LuaSocket/Source/src/inet.cpp` - `Plugins/UnLuaExtensions/LuaSocket/Source/src/options.cpp` - `Plugins/UnLuaExtensions/LuaSocket/Source/src/udp.cpp` - `Plugins/UnLuaExtensions/LuaSocket/Source/src/wsocket.cpp` - `Source/UnLua/Private/BaseLib/LuaLib_Object.cpp` ## 12. 其他编译/运行问题修复 在 UE 5.8 适配过程中同时修复了以下独立问题: - `Source/UnLua/Private/Registries/ClassRegistry.cpp` 中移除重复的 `Classes.Remove(Class)` 调用,避免 `Unregister` 内部重复操作导致集合状态异常。 - `Source/UnLua/Private/UnLuaBase.cpp` 中 `UNLUA_LOGERROR` 缺少 `__FUNCTION__` 参数,已补充 `ANSI_TO_TCHAR(__FUNCTION__)`。 - `Source/UnLua/Private/UnLuaConsoleCommands.cpp` 中 `FString::Printf` 原写法在较新编译器下格式检查更严格,已改为一次性传入完整格式字符串与参数。 涉及文件: - `Source/UnLua/Private/Registries/ClassRegistry.cpp` - `Source/UnLua/Private/UnLuaBase.cpp` - `Source/UnLua/Private/UnLuaConsoleCommands.cpp` > 当前 `P1GameEditor Win64 Development` 整编结果:**Succeeded,无 C4996 / C4191 / C4459 警告**。