环境
- Unreal Engine:5.8.1
- UnLua:2.3.6
- 平台:Windows 64-bit
问题描述
UnLua 为 Blueprint User Defined Struct 和 Blueprint User Defined Enum 生成 IntelliSense 定义时,使用了 Unreal 内部反射名称,而不是用户在编辑器中定义的原始名称。
具体表现为:
- 结构体字段带有数字编号和 GUID 后缀。
- 枚举项被生成为
NewEnumerator0、NewEnumerator1 等内部名称。
- Blueprint 枚举自动生成的
_MAX 占位项也会出现在 IntelliSense 中。
- 生成的代码提示与 Lua 运行时实际使用的字段名不一致。
复现示例
创建一个 Blueprint User Defined Struct,字段如下:
CaseId
FamilyName
GivenName
Origin
UnLua 当前生成:
---@class FFTravelerCaseData
---@field public CaseId_2_017948BB457CC28338A868982DA92B21 FGuid
---@field public FamilyName_13_41C655204FB61C895543EE9CC1E14CDD string
---@field public GivenName_14_B6752E0D4806BDBBA0F9E1B88CAF1EE1 string
---@field public Origin_15_429CFC92412CA6D0B32AC1A32B139DF8 string
但 Lua 运行时实际使用用户定义的字段名:
local caseId = CaseData.CaseId
local familyName = CaseData.FamilyName
Blueprint User Defined Enum 也存在相同问题。
假设枚举定义如下:
Waiting
TravelerArriving
Inspecting
AwaitingDecision
Resolving
DayFinished
UnLua 当前生成:
---@class EInspectionState
---@field public NewEnumerator0 integer
---@field public NewEnumerator1 integer
---@field public NewEnumerator2 integer
---@field public NewEnumerator3 integer
---@field public NewEnumerator4 integer
---@field public NewEnumerator5 integer
---@field public EInspectionState_MAX integer
期望结果
结构体应当生成用户定义的字段名:
---@class FFTravelerCaseData
---@field public CaseId FGuid
---@field public FamilyName string
---@field public GivenName string
---@field public Origin string
枚举应当生成用户定义的枚举项名称,并排除自动生成的 _MAX 占位项:
---@class EInspectionState
---@field public Waiting integer
---@field public TravelerArriving integer
---@field public Inspecting integer
---@field public AwaitingDecision integer
---@field public Resolving integer
---@field public DayFinished integer
原因分析
UnLuaIntelliSense.cpp 当前使用以下旧版本接口生成结构体字段名:
对于 Blueprint User Defined Struct,GetName() 返回的是 Unreal 内部属性名称,因此会包含字段编号和 GUID。
Unreal 已经提供了对应的新接口:
FField::GetAuthoredName()
对于 User Defined Struct,该接口最终会通过:
UUserDefinedStruct::GetAuthoredNameForField()
返回用户定义的、非本地化的可读字段名。
枚举同样存在此问题。当前生成器使用:
Enum->GetNameStringByIndex(i)
对于 Blueprint User Defined Enum,该接口会返回 NewEnumerator0 等内部名称。
Unreal 提供了以下接口获取用户定义的枚举项名称:
Enum->GetAuthoredNameStringByIndex(i)
这个问题不仅影响显示效果。当前生成的 IntelliSense 注解会提示无法对应 Lua 运行时访问方式的内部名称。
建议修复
diff --git a/Source/UnLuaEditor/Private/UnLuaIntelliSense.cpp b/Source/UnLuaEditor/Private/UnLuaIntelliSense.cpp
--- a/Source/UnLuaEditor/Private/UnLuaIntelliSense.cpp
+++ b/Source/UnLuaEditor/Private/UnLuaIntelliSense.cpp
@@
#include "Binding.h"
+#include "Engine/UserDefinedEnum.h"
#include "ObjectEditorUtils.h"
#include "UnLuaInterface.h"
@@
- const int32 Num = Enum->NumEnums();
+ // Blueprint User Defined Enum 会在末尾自动添加一个内部 _MAX 项
+ const int32 Num =
+ Enum->NumEnums() - (Enum->IsA<UUserDefinedEnum>() ? 1 : 0);
for (int32 i = 0; i < Num; ++i)
{
+ const FString EnumValueName =
+ EscapeSymbolName(*Enum->GetAuthoredNameStringByIndex(i));
+
Ret += FString::Printf(
TEXT("\r\n---@field %s %s %s"),
TEXT("public"),
- *Enum->GetNameStringByIndex(i),
+ *EnumValueName,
TEXT("integer")
);
}
@@
FString TypeName = IntelliSense::GetTypeName(Property);
+
+ const FString PropertyName =
+ EscapeSymbolName(*Property->GetAuthoredName());
+
Ret += FString::Printf(
TEXT("---@field %s %s %s"),
*AccessLevel,
- *Property->GetName(),
+ *PropertyName,
*TypeName
);
环境
问题描述
UnLua 为 Blueprint User Defined Struct 和 Blueprint User Defined Enum 生成 IntelliSense 定义时,使用了 Unreal 内部反射名称,而不是用户在编辑器中定义的原始名称。
具体表现为:
NewEnumerator0、NewEnumerator1等内部名称。_MAX占位项也会出现在 IntelliSense 中。复现示例
创建一个 Blueprint User Defined Struct,字段如下:
UnLua 当前生成:
但 Lua 运行时实际使用用户定义的字段名:
Blueprint User Defined Enum 也存在相同问题。
假设枚举定义如下:
UnLua 当前生成:
期望结果
结构体应当生成用户定义的字段名:
枚举应当生成用户定义的枚举项名称,并排除自动生成的
_MAX占位项:原因分析
UnLuaIntelliSense.cpp当前使用以下旧版本接口生成结构体字段名:Property->GetName()对于 Blueprint User Defined Struct,
GetName()返回的是 Unreal 内部属性名称,因此会包含字段编号和 GUID。Unreal 已经提供了对应的新接口:
FField::GetAuthoredName()对于 User Defined Struct,该接口最终会通过:
UUserDefinedStruct::GetAuthoredNameForField()返回用户定义的、非本地化的可读字段名。
枚举同样存在此问题。当前生成器使用:
Enum->GetNameStringByIndex(i)对于 Blueprint User Defined Enum,该接口会返回
NewEnumerator0等内部名称。Unreal 提供了以下接口获取用户定义的枚举项名称:
Enum->GetAuthoredNameStringByIndex(i)这个问题不仅影响显示效果。当前生成的 IntelliSense 注解会提示无法对应 Lua 运行时访问方式的内部名称。
建议修复