• 运行时创建UField[贰]


    上一回实现了运行时创建枚举,这次再试试结构体,虚幻中的反射结构体是UScriptStruct的实例.同样,蓝图新建的结构体是UUserDefinedStruct的实例.
    结构体由多个字段构成,虚幻中称为属性,即FProperty,FProperty描述了一个变量在一段内存的位置和大小,结构体通过链表来保存各个字段.
    要创建一个结构体,需要创建一个继承自UScriptStruct的类ULuaGeneratedStruct,然后根据所需要的字段及其类型创建FProperty,
    这里并不需要手动去操作PropertyLink这个链表成员,只需要新建Fproperty,结束后调用StaticLink即可完成链表关联.
    简要实现如下:

    // Fill out your copyright notice in the Description page of Project Settings.
    
    
    #include "LuaGeneratedStruct.h"
    
    
    ULuaGeneratedStruct* ULuaGeneratedStruct::GenerateStruct(const FString& InStructName, const TMap<FString, int32>& InVariables)
    {
    	ULuaGeneratedStruct* NewStruct = FindObject<ULuaGeneratedStruct>(ANY_PACKAGE, *InStructName);
    	if (!NewStruct)
    	{
    		NewStruct = NewObject<ULuaGeneratedStruct>(GetTransientPackage(), *InStructName, RF_Public | RF_Standalone | RF_Transient);
    		NewStruct->SetMetaData(TEXT("BlueprintType"), TEXT("true"));
    		NewStruct->Bind();
    		NewStruct->StaticLink(true);
    		NewStruct->AddToRoot();
    	}
    	else
    	{
    		return NewStruct;
    	}
    
    	int32 PropCount = 0;
    	int32 PropOffset = 0;
    	EObjectFlags ObjectFlags = EObjectFlags::RF_Standalone;
    	EPropertyFlags PropertyFlags = EPropertyFlags::CPF_None;
    	bool bIsPOD = true;
    	for (const TPair<FString, int32>& It : InVariables)
    	{
    		FProperty* NewProp = nullptr;
    		UE4CodeGen_Private::EPropertyGenFlags PropertyType = (UE4CodeGen_Private::EPropertyGenFlags)(It.Value);
    		switch (PropertyType)
    		{
    		case UE4CodeGen_Private::EPropertyGenFlags::Int8:
    			NewProp = new FInt8Property(NewStruct, FName(*It.Key), ObjectFlags, PropOffset, PropertyFlags);
    			NewProp->SetPropertyFlags(EPropertyFlags::CPF_IsPlainOldData);
    			break;
    
    		case UE4CodeGen_Private::EPropertyGenFlags::Byte:
    			NewProp = new FByteProperty(NewStruct, FName(*It.Key), ObjectFlags, PropOffset, PropertyFlags, nullptr);
    			NewProp->SetPropertyFlags(EPropertyFlags::CPF_IsPlainOldData);
    			break;
    
    		case UE4CodeGen_Private::EPropertyGenFlags::Int16:
    			NewProp = new FInt16Property(NewStruct, FName(*It.Key), ObjectFlags, PropOffset, PropertyFlags);
    			NewProp->SetPropertyFlags(EPropertyFlags::CPF_IsPlainOldData);
    			break;
    
    		case UE4CodeGen_Private::EPropertyGenFlags::UInt16:
    			NewProp = new FUInt16Property(NewStruct, FName(*It.Key), ObjectFlags, PropOffset, PropertyFlags);
    			NewProp->SetPropertyFlags(EPropertyFlags::CPF_IsPlainOldData);
    			break;
    
    		case UE4CodeGen_Private::EPropertyGenFlags::Int:
    			NewProp = new FIntProperty(NewStruct, FName(*It.Key), ObjectFlags, PropOffset, PropertyFlags);
    			NewProp->SetPropertyFlags(EPropertyFlags::CPF_IsPlainOldData);
    			break;
    
    		case UE4CodeGen_Private::EPropertyGenFlags::UInt32:
    			NewProp = new FUInt32Property(NewStruct, FName(*It.Key), ObjectFlags, PropOffset, PropertyFlags);
    			NewProp->SetPropertyFlags(EPropertyFlags::CPF_IsPlainOldData);
    			break;
    
    		case UE4CodeGen_Private::EPropertyGenFlags::Int64:
    			NewProp = new FInt64Property(NewStruct, FName(*It.Key), ObjectFlags, PropOffset, PropertyFlags);
    			NewProp->SetPropertyFlags(EPropertyFlags::CPF_IsPlainOldData);
    			break;
    
    		case UE4CodeGen_Private::EPropertyGenFlags::UInt64:
    			NewProp = new FUInt64Property(NewStruct, FName(*It.Key), ObjectFlags, PropOffset, PropertyFlags);
    			NewProp->SetPropertyFlags(EPropertyFlags::CPF_IsPlainOldData);
    			break;
    
    		case UE4CodeGen_Private::EPropertyGenFlags::Float:
    			NewProp = new FFloatProperty(NewStruct, FName(*It.Key), ObjectFlags, PropOffset, PropertyFlags);
    			NewProp->SetPropertyFlags(EPropertyFlags::CPF_IsPlainOldData);
    			break;
    
    		case UE4CodeGen_Private::EPropertyGenFlags::Str:
    			NewProp = new FStrProperty(NewStruct, FName(*It.Key), ObjectFlags, PropOffset, PropertyFlags);
    			bIsPOD = false;
    			break;
    
    		case UE4CodeGen_Private::EPropertyGenFlags::Array:
    			NewProp = new FArrayProperty(NewStruct, FName(*It.Key), ObjectFlags, PropOffset, PropertyFlags, EArrayPropertyFlags::None);
    			bIsPOD = false;
    			break;
    
    		case UE4CodeGen_Private::EPropertyGenFlags::Map:
    			NewProp = new FMapProperty(NewStruct, FName(*It.Key), ObjectFlags, PropOffset, PropertyFlags, EMapPropertyFlags::None);
    			bIsPOD = false;
    			break;
    		}
    		++PropCount;
    		PropOffset += NewProp->GetSize();
    	}
    
    	if(bIsPOD)
    	{
    		NewStruct->StructFlags = (EStructFlags)(NewStruct->StructFlags | EStructFlags::STRUCT_IsPlainOldData);
    	}
    	NewStruct->Bind();
    	NewStruct->StaticLink(true);
    	return NewStruct;
    }
    

    LUA中新建结构体如下:

    --结构体名字,描述成员名字和类型
    local TmpStructName = 'XQStruct'
    	local TmpVatList =
    	{
    		['MyID'] = UnrealPropertyType.EPropertyGenFlags.Int,
    		['MyName'] = UnrealPropertyType.EPropertyGenFlags.Str
    	}
    
    	local NewStruct = LuaGeneratedStruct:GenerateStruct(TmpStructName, TmpVatList)
            --用LUA表填充结构体实例
    	local XQVal = 
    	{
    		['MyID'] = 111,
    		['MyName'] = 'efrewfr34'
    	}
    	local MyT = Unreal.LuaNewStruct('XQStruct', XQVal)
    	print(MyT.MyID, MyT.MyName)
    
    
    --虚幻中属性类型对应的枚举值如下,取自UE4CodeGen_Private::EPropertyGenFlags
    LuaGeneratedEnum = LuaGeneratedEnum or Unreal.LuaGetUnrealCDO('LuaGeneratedEnum')
    
    LuaGeneratedStruct = LuaGeneratedStruct or Unreal.LuaGetUnrealCDO('LuaGeneratedStruct')
    
    UnrealProperty = UnrealProperty or {}
    
    UnrealProperty.EPropertyGenFlags =
    {
    	None              = 0x00,
    	Byte              = 0x00,
    	Int8              = 0x01,
    	Int16             = 0x02,
    	Int               = 0x03,
    	Int64             = 0x04,
    	UInt16            = 0x05,
    	UInt32            = 0x06,
    	UInt64            = 0x07,
    	UnsizedInt        = 0x08,
    	UnsizedUInt       = 0x09,
    	Float             = 0x0A,
    	Double            = 0x0B,
    	Bool              = 0x0C,
    	SoftClass         = 0x0D,
    	WeakObject        = 0x0E,
    	LazyObject        = 0x0F,
    	SoftObject        = 0x10,
    	Class             = 0x11,
    	Object            = 0x12,
    	Interface         = 0x13,
    	Name              = 0x14,
    	Str               = 0x15,
    	Array             = 0x16,
    	Map               = 0x17,
    	Set               = 0x18,
    	Struct            = 0x19,
    	Delegate          = 0x1A,
    	InlineMulticastDelegate = 0x1B,
    	SparseMulticastDelegate = 0x1C,
    	Text              = 0x1D,
    	Enum              = 0x1E,
    	FieldPath         = 0x1F,
    
    	NativeBool        = 0x20
    }
    
    
    return UnrealProperty
    
  • 相关阅读:
    深入了解接口
    深入.NET平台C#编程 测试题分析
    如何设计高级的数据库
    数据库查询的基础技巧
    回顾Spring MVC_01_概述_入门案例
    初学My Batis之入门
    Spring MVC之视图解析器和URL-Pattern的配置方案
    SpringMVC之入门
    WebService入门
    Spring之实现任务调度
  • 原文地址:https://www.cnblogs.com/rpg3d/p/12601602.html
Copyright © 2020-2023  润新知