运行时创建UField

虚幻4中的蓝图系统可以在运行时创建枚举/结构体/类(把编辑器看作一个基于Runtime引擎完整的游戏产品),非常好用,
但是在实际使用中由于蓝图只能在编辑器创建,还是略有麻烦,所以准备在其他脚本语言实现无编辑器,此处以LUA为例.

inside unreal系列文章有介绍反射系统,里面提以枚举入手,此处同样,无论如何枚举最简单.
虚幻里面的C++定义的反射枚举都是UEnum类(或其子类)的实例,编辑器中创建的蓝图枚举是其子类UUserDefinedEnum的实例,
显然如果要用LUA新建枚举,也要新建一个子类ULuaGeneratedEnum,尽管可以直接使用UUserDefinedEnum或者UEnum,但单独定义一个子类,
方便后续处理,比如某些时候可能需要搜易所有LUA新建的枚举时就很有用了,至于名字则是参考虚幻内置python插件的命名规则,
ULuaGeneratedEnum的实现代码也可以参考python版的反射枚举.简要实现如下:

// Fill out your copyright notice in the Description page of Project Settings.


#include "LuaGeneratedEnum.h"
#include "lua/lua.hpp"



ULuaGeneratedEnum* ULuaGeneratedEnum::GenerateEnum(const FString& InEnumName, const TMap<FString, int32>& InKV)
{
	ULuaGeneratedEnum* NewEnum = FindObject<ULuaGeneratedEnum>(ANY_PACKAGE, *InEnumName);
	if (!NewEnum)
	{
		NewEnum = NewObject<ULuaGeneratedEnum>(GetTransientPackage(), *InEnumName, RF_Public | RF_Standalone | RF_Transient);
		NewEnum->SetMetaData(TEXT("BlueprintType"), TEXT("true"));
		NewEnum->AddToRoot();
	}

	TArray<TPair<FName, int64>> TmpKV;
	for (const TPair<FString, int32>& It : InKV)
	{
		TPair<FName, int64> TmpNew;
		TmpNew.Key = *It.Key;
		TmpNew.Value = (int64)It.Value;
		TmpKV.Add(TmpNew);
	}

	NewEnum->SetEnums(TmpKV, UEnum::ECppForm::Namespaced);

	return NewEnum;
}

FString ULuaGeneratedEnum::GenerateFullEnumName(const TCHAR* InEnumName) const
{
	return Super::GenerateFullEnumName(InEnumName);
}

FText ULuaGeneratedEnum::GetDisplayNameTextByIndex(int32 InIndex) const
{
	FText Ret  = FText::FromString(GetName() + FString("_") + GetNameByIndex(InIndex).ToString());
	return Ret;
}

将函数ULuaGeneratedEnum* ULuaGeneratedEnum::GenerateEnum定义为蓝图可访问的静态函数,即可在LUA中调用了,LUA中创建枚举用法如下:

        --枚举名字(ULuaGeneratedEnum实例的名字)
        local NewEnumName = 'LuaVersion'
        local EnumValue = 
	{
		['A'] = 51,
		['B'] = 52,
		['C'] = 53
	}
        --获取ClassDefaultObject,用法根据不同lua插件各有不同
	LuaGeneratedEnum = Unreal.LuaGetUnrealCDO('LuaGeneratedEnum')
	LuaGeneratedEnum:GenerateEnum(NewEnumName, EnumValue)

至此就可以在蓝图中右键即可搜索到新建的枚举了!这个个枚举没法在蓝图中序列化,这个枚举后续主要是给LUA和虚幻反射系统使用,先不管蓝图.

原文地址:https://www.cnblogs.com/rpg3d/p/12601292.html