UE4类型系统、语言修饰符和元数据


在编译之前,通过UHT扫描头文件中特定的宏来生成相关代码(*.generated.h / *.gen.cpp),然后再一起编译链接进游戏,来生成类型系统扩展语言修饰符收集元数据UMetaData

 

类型系统在对象之外,提供了一个静态信息载体,不仅描述了对象自身,还能构建起来对象之间的派生从属关系

通过查询类型系统数据,可实现强大的运行时类型识别(RTTI,Run-Time Type Identification)。例如:根据类型创建对象,遍历和修改属性成员,根据名字来调用函数。

默认对象(Class Default Object,简称CDO)、反射(Reflection)、垃圾回收(Garbage Collection,简称GC)、序列化(Serialization)都是在类型系统的基础上实现的

 

通过修饰符来在编程语言层面扩展c++能力,引擎底层提供对修饰符实现,与引擎深度结合,程序员可通过配置修饰符让对象、属性或函数拥有更强大的能力

修饰符可优雅地实现c++与蓝图的互操作、编辑器支持、网络同步等方面的功能

例如:Config修饰符来从指定ini文件中读取数据、Transient修饰符来指明不需要序列化、Exec修饰符来指明该函数可被控制台调用

Replicated修饰符给属性加上同步属性、Server修饰符表明该函数为一个对服务端的RPC调用,等等

 

元数据UMetaData其实就是个键值对的集合,用于为编辑器提供分类、友好名字、提示等信息,Android、IOS、DS版本不包含此信息(相关逻辑包裹在宏WITH_EDITORONLY_DATA中)

 

类型系统

 

UField为类型系统的统一基类,可以方便获取元数据UMetaData

UStructUScriptStructUFunctionUClass的基类,统一提供了对属性的支持;UStruct* SuperStruct指向继承的基类

③ UFunction只可包含属性,来作为函数的输入输出参数

FProperty为属性的基类,具体包括:

FBoolProperty

FInt8Property、FInt16Property、FIntProperty、FInt64Property

FByteProperty、FUInt16Property、FUInt32Property、FUInt64Property

FFloatProperty、FDoubleProperty

FNameProperty、FTextProperty、FStrProperty

FArrayProperty、FMapProperty、FSetProperty

FMulticastInlineDelegateProperty、FMulticastSparseDelegateProperty、FDelegateProperty

FEnumProperty

FStructProperty

FObjectProperty、FInterfaceProperty、FClassProperty

FWeakObjectProperty、FLazyObjectProperty、FSoftObjectProperty、FSoftClassProperty

 

UEnum

① 被宏UENUM修饰的普通的枚举

② 被宏UENUM修饰的enum class的类型

/** The network role of an actor on a local/remote network context */ UENUM()
enum ENetRole
{
    /** No role at all. */
    ROLE_None,
    /** Locally simulated proxy of this actor. */
    ROLE_SimulatedProxy,
    /** Locally autonomous proxy of this actor. */
    ROLE_AutonomousProxy,
    /** Authoritative control over the actor. */
    ROLE_Authority,
    ROLE_MAX,
};


// Must match enum ESamplerFilter in RHIDefinitions.h
UENUM()
enum class ETextureSamplerFilter : uint8
{
    Point,
    Bilinear,
    Trilinear,
    AnisotropicPoint,
    AnisotropicLinear,
};


/**
 * Determines case sensitivity options for string comparisons. 
 * @note Mirrored from Engine\Source\Runtime\Core\Public\Containers\UnrealString.h
 */ UENUM()
namespace ESearchCase
{
    enum Type
    {
        CaseSensitive,
        IgnoreCase,
    };
}

 

UScriptStruct

被宏USTRUCT修饰的结构体的类型为UScriptStruct,只可包含属性,可以理解为C++中的POD(Plain Old Data)结构体。

是一种“轻量UObject,拥有和UObject一样的反射支持,序列化,网络复制等。但其不受GC管理。

/**
 * A point or direction FVector in 3d space.
 * @note The full C++ class is located here: Engine\Source\Runtime\Core\Public\Math\Vector.h
 */ USTRUCT(immutable, noexport, BlueprintType, meta=(HasNativeMake="Engine.KismetMathLibrary.MakeVector", HasNativeBreak="Engine.KismetMathLibrary.BreakVector"))
struct FVector
{
    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category=Vector, SaveGame)
    float X;

    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category=Vector, SaveGame)
    float Y;

    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category=Vector, SaveGame)
    float Z;
};

/**
 * A plane definition in 3D space.
 * @note The full C++ class is located here: Engine\Source\Runtime\Core\Public\Math\Plane.h
 */ USTRUCT(immutable, noexport, BlueprintType)
struct FPlane : public FVector
{
    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category=Plane, SaveGame)
    float W;
};


/** Struct to help hold information about packages needing to be fully-loaded for DLC, etc. */ USTRUCT()
struct FFullyLoadedPackagesInfo
{
    GENERATED_USTRUCT_BODY()

    /** When to load these packages */ UPROPERTY()
    TEnumAsByte<enum EFullyLoadPackageType> FullyLoadType;

    /** When this map or gametype is loaded, the packages in the following array will be loaded and added to root, then removed from root when map is unloaded */ UPROPERTY()
    FString Tag;

    /** The list of packages that will be fully loaded when the above Map is loaded */ UPROPERTY()
    TArray<FName> PackagesToLoad;

    /** List of objects that were loaded, for faster cleanup */ UPROPERTY()
    TArray<class UObject*> LoadedObjects;


    FFullyLoadedPackagesInfo()
        : FullyLoadType(0)
    {
    }

};

/**
 * FFocusEvent is used when notifying widgets about keyboard focus changes
 * It is passed to event handlers dealing with keyboard focus
 */ USTRUCT(BlueprintType)
struct FFocusEvent
{
    GENERATED_USTRUCT_BODY()

public:

    /**
     * UStruct Constructor.  Not meant for normal usage.
     */
    FFocusEvent()
        : Cause(EFocusCause::SetDirectly)
        , UserIndex(0)
    { }

    /**
     * Constructor.  Events are immutable once constructed.
     *
     * @param  InCause  The cause of the focus event
     */
    FFocusEvent(const EFocusCause InCause, uint32 InUserIndex)
        : Cause(InCause)
        , UserIndex(InUserIndex)
    { }

    /**
     * Queries the reason for the focus change
     *
     * @return  The cause of the focus change
     */
    EFocusCause GetCause() const
    {
        return Cause;
    }

    /**
     * Queries the user that is changing focus
     *
     * @return  The user that is changing focus
     */
    uint32 GetUser() const
    {
        return UserIndex;
    }

private:

    /** The cause of the focus change */
    EFocusCause Cause;

    /** User that is changing focus*/
    uint32 UserIndex;
};

 

UClass 

被宏UCLASS修饰的UObject的类型为UClass,可包含属性和函数

UObject对象上调用GetClass()可获得它的UClass对象,在UClass对象上调用GetClass()返回的是自己本身,这样可以用来区分对象和类型数据。

UCLASS(Transient, BlueprintType)
class UMG_API UUMGSequencePlayer : public UObject, public IMovieScenePlayer  // IMovieScenePlayer为普通的c++纯虚类
{
    GENERATED_UCLASS_BODY()

    // ... ...
};


/**
 * The user widget is extensible by users through the WidgetBlueprint.
 */ UCLASS(Abstract, editinlinenew, BlueprintType, Blueprintable, meta=( DontUseGenericSpawnObject="True", DisableNativeTick) )
class UMG_API UUserWidget : public UWidget, public INamedSlotInterface  // INamedSlotInterface为虚幻Interface类型
{
    GENERATED_BODY()

    friend class SObjectWidget;
public:
    UUserWidget(const FObjectInitializer& ObjectInitializer);

    //UObject interface
    virtual class UWorld* GetWorld() const override;
    virtual void PostDuplicate(bool bDuplicateForPIE) override;
    virtual void BeginDestroy() override;
    virtual void PostLoad() override;
    virtual void Serialize(FArchive& Ar) override;
    //~ End UObject Interface

    void DuplicateAndInitializeFromWidgetTree(UWidgetTree* InWidgetTree);

    virtual bool Initialize();

    EWidgetTickFrequency GetDesiredTickFrequency() const { return TickFrequency; }

    // ... ...

public:
    
    // ... ...

    /**
     * Adds it to the game's viewport and fills the entire screen, unless SetDesiredSizeInViewport is called
     * to explicitly set the size.
     *
     * @param ZOrder The higher the number, the more on top this widget will be.
     */ UFUNCTION(BlueprintCallable, BlueprintCosmetic, Category="User Interface|Viewport", meta=( AdvancedDisplay = "ZOrder" ))
    void AddToViewport(int32 ZOrder = 0);

    /**
     * Adds the widget to the game's viewport in a section dedicated to the player.  This is valuable in a split screen
     * game where you need to only show a widget over a player's portion of the viewport.
     *
     * @param ZOrder The higher the number, the more on top this widget will be.
     */ UFUNCTION(BlueprintCallable, BlueprintCosmetic, Category="User Interface|Viewport", meta=( AdvancedDisplay = "ZOrder" ))
    bool AddToPlayerScreen(int32 ZOrder = 0);

    /**
     * Removes the widget from the viewport.
     */ UFUNCTION(BlueprintCallable, BlueprintCosmetic, Category="User Interface|Viewport", meta=( DeprecatedFunction, DeprecationMessage="Use RemoveFromParent instead" ))
    void RemoveFromViewport();

    /**
     * Removes the widget from its parent widget.  If this widget was added to the player's screen or the viewport
     * it will also be removed from those containers.
     */
    virtual void RemoveFromParent() override;

    // ... ...

public:

    // ... ...

    /** Setting this flag to true, allows this widget to accept focus when clicked, or when navigated to. */ UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Interaction")
    uint8 bIsFocusable : 1;

    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Input")
    uint8 bStopAction : 1;

    /** If a widget has an implemented tick blueprint function */ UPROPERTY()
    uint8 bHasScriptImplementedTick : 1;

    /** If a widget has an implemented paint blueprint function */ UPROPERTY()
    uint8 bHasScriptImplementedPaint : 1;

protected:

    /** Has this widget been initialized by its class yet? */
    uint8 bInitialized : 1;

    /** If we're stopping all animations, don't allow new animations to be created as side-effects. */
    uint8 bStoppingAllAnimations : 1;

    // ... ...
};

UCLASS(abstract, BlueprintType, MinimalAPI, HideCategories = (Thumbnail))
class UMaterialInterface : public UObject, public IBlendableInterface, public IInterface_AssetUserData  // UMaterialInterface为UObject,继承了2个Interface
{
    GENERATED_UCLASS_BODY()

    /** SubsurfaceProfile, for Screen Space Subsurface Scattering */ UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Material, meta = (DisplayName = "Subsurface Profile"))
    class USubsurfaceProfile* SubsurfaceProfile;

    /* -------------------------- */

    /** A fence to track when the primitive is no longer used as a parent */
    FRenderCommandFence ParentRefFence;

protected:
    /** The Lightmass settings for this object. */ UPROPERTY(EditAnywhere, Category=Lightmass)
    struct FLightmassMaterialInterfaceSettings LightmassSettings;

    // ... ...

public:

    //~ Begin IInterface_AssetUserData Interface
    ENGINE_API virtual void AddAssetUserData(UAssetUserData* InUserData) override;
    ENGINE_API virtual void RemoveUserDataOfClass(TSubclassOf<UAssetUserData> InUserDataClass) override;
    ENGINE_API virtual UAssetUserData* GetAssetUserDataOfClass(TSubclassOf<UAssetUserData> InUserDataClass) override;
    //~ End IInterface_AssetUserData Interface

    // ... ...

    //~ Begin Begin Interface IBlendableInterface
    ENGINE_API virtual void OverrideBlendableSettings(class FSceneView& View, float Weight) const override;
    //~ Begin End Interface IBlendableInterface

    /** Walks up parent chain and finds the base Material that this is an instance of. Just calls the virtual GetMaterial() */ UFUNCTION(BlueprintCallable, Category="Rendering|Material")
    ENGINE_API UMaterial* GetBaseMaterial();

    // ... ...
};

 

UInterface

一个自定义的UObject类,只能有一个UObject基类,但可以有多个UInterface接口

UINTERFACE宏即UCLASS宏。    #define UINTERFACE(...) UCLASS()

因此,接口也是被宏UCLASS修饰的UObject,其类型也为UClass,但它只可包含函数

UClass里保存了一个TArray<FImplementedInterface> Interfaces数组,FImplementedInterface中的成员UClass* Class来支持查询当前类实现了那些接口。

UINTERFACE需要定义两个类:一个是UXXXInterface类,继承UInterface,其中什么数据都没有。另一个是IXXXInterface类,什么都不继承。

UINTERFACE用两个类来实现,可以避免菱形继承导致的虚表扩张及二义性。外部类如果要继承接口的话,只用继承IXXXInterface类即可,非常干净。

UINTERFACE(meta=( CannotImplementInterfaceInBlueprint ))
class UMG_API UNamedSlotInterface : public UInterface
{
    GENERATED_UINTERFACE_BODY()  // 使用该宏,需要在cpp中实现UNamedSlotInterface::UNamedSlotInterface(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer) {}构造函数
};

class UMG_API INamedSlotInterface
{
    GENERATED_IINTERFACE_BODY()

public:

    /**  */
    virtual void GetSlotNames(TArray<FName>& SlotNames) const = 0;

    /**  */
    virtual UWidget* GetContentForSlot(FName SlotName) const = 0;

    /**  */
    virtual void SetContentForSlot(FName SlotName, UWidget* Content) = 0;

    /**  */
    bool ContainsContent(UWidget* Content) const;

    /**  */
    void ReleaseNamedSlotSlateResources(bool bReleaseChildren);

#if WITH_EDITOR
    void SetNamedSlotDesignerFlags(EWidgetDesignFlags NewFlags);
#endif
};

// ---------------------------------------------------------------------------------------------------------------------------------
 UINTERFACE()
class MOVIESCENE_API UMovieSceneCustomClockSource : public UInterface
{
    GENERATED_BODY()
};

/**
 * 
 */
class IMovieSceneCustomClockSource
{
public:

    GENERATED_BODY()

    UFUNCTION()
    virtual void OnTick(float DeltaSeconds, float InPlayRate) {}

    UFUNCTION()
    virtual void OnStartPlaying(const FQualifiedFrameTime& InStartTime) {}

    UFUNCTION()
    virtual void OnStopPlaying(const FQualifiedFrameTime& InStopTime) {}

    UFUNCTION()
    virtual FFrameTime OnRequestCurrentTime(const FQualifiedFrameTime& InCurrentTime, float InPlayRate) { return 0; }
};

// ---------------------------------------------------------------------------------------------------------------------------------

/** Interface for assets which contain gameplay tags */ UINTERFACE(Blueprintable, MinimalAPI, meta=(CannotImplementInterfaceInBlueprint))
class UGameplayTagAssetInterface : public UInterface
{
    GENERATED_UINTERFACE_BODY() // 使用该宏,需要在cpp中实现UGameplayTagAssetInterface::UGameplayTagAssetInterface(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer) {}构造函数
};

class GAMEPLAYTAGS_API IGameplayTagAssetInterface
{
    GENERATED_IINTERFACE_BODY()

    /**
     * Get any owned gameplay tags on the asset
     * 
     * @param OutTags    [OUT] Set of tags on the asset
     */ UFUNCTION(BlueprintCallable, Category = GameplayTags)
    virtual void GetOwnedGameplayTags(FGameplayTagContainer& TagContainer) const=0;

    /**
     * Check if the asset has a gameplay tag that matches against the specified tag (expands to include parents of asset tags)
     * 
     * @param TagToCheck    Tag to check for a match
     * 
     * @return True if the asset has a gameplay tag that matches, false if not
     */ UFUNCTION(BlueprintCallable, Category=GameplayTags)
    virtual bool HasMatchingGameplayTag(FGameplayTag TagToCheck) const;

    /**
     * Check if the asset has gameplay tags that matches against all of the specified tags (expands to include parents of asset tags)
     * 
     * @param TagContainer            Tag container to check for a match
     * 
     * @return True if the asset has matches all of the gameplay tags, will be true if container is empty
     */ UFUNCTION(BlueprintCallable, Category=GameplayTags)
    virtual bool HasAllMatchingGameplayTags(const FGameplayTagContainer& TagContainer) const;

    /**
     * Check if the asset has gameplay tags that matches against any of the specified tags (expands to include parents of asset tags)
     * 
     * @param TagContainer            Tag container to check for a match
     * 
     * @return True if the asset has matches any of the gameplay tags, will be false if container is empty
     */
    UFUNCTION(BlueprintCallable, Category=GameplayTags)
    virtual bool HasAnyMatchingGameplayTags(const FGameplayTagContainer& TagContainer) const;
};

 

FProperty

FXXXProperty用来描述:

USTRUCT宏修饰的结构体中被UPROPERTY宏修饰的成员变量

UCLASS宏修饰的UObject中被UPROPERTY宏修饰的成员变量

UFUNCTION宏修饰的成员函数的参数及返回值

4.25版本之后,属性相关类型的名称从UXXXProperty修改为FXXXProperty。继承的基类也不再是UField --> UObject,而是FField

如果你在代码中仍然使用UXXXProperty,编译器会将其宏替换为FXXXProperty,并得到如下编译warning:

warning C4996: UProperty has been renamed to FProperty Please update your code to the new API before upgrading to the next release, otherwise your project will no longer compile.

详见:G:\svn\UnrealEngine\Engine\Source\Runtime\CoreUObject\Public\UObject\DefineUPropertyMacros.h

另外,可以调用FField* FField::CreateFromUField(UField* InField)函数将一个UField转换为FField

 

布尔、整型、浮点型

FBoolProperty(bool、TEnumAsByte<ENetRole>)

FNumericProperty:FInt8Property(int8)、FInt16Property(int16)、FIntProperty(int32)、FInt64Property(int64)、

                                 FByteProperty(uint8)、FUInt16Property(uint16)、FUInt32Property(uint32)、FUInt64Property(uint64)、

                                 FFloatProperty(float)、FDoubleProperty(double)

字符串 

FName:FNameProperty

FText:FTextProperty

FString:FStrProperty

 

容器 

TArray:FArrayProperty

TMap:FMapProperty

TSet:FSetProperty

 

Delegate

DECLARE_DYNAMIC_MULTICAST_DELEGATE_*:FMulticastInlineDelegateProperty

DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE*:FMulticastSparseDelegateProperty

DECLARE_DYNAMIC_DELEGATE*:FDelegateProperty

 

枚举、结构体、接口、Object等复合类型

UENUM宏修饰的enum class:FEnumProperty

USTRUCT宏修饰的结构体(如:FVector、FPlane、FSoftObjectPath、FSoftClassPath):FStructProperty

TScriptInterface<UNamedSlotInterface>、TScriptInterface <INamedSlotInterface>:FInterfaceProperty

UObject*、UStruct、UScriptStruct、UFunction、UEnum、UField:FObjectProperty

UClass*、TSubclassOf<UObject>:FClassProperty

TWeakObjectPtr<UObject>:FWeakObjectProperty   注:FWeakObjectPtr不能作为属性

TLazyObjectPtr<UObject>:FLazyObjectProperty  注:FLazyObjectPtr不能作为属性

TSoftObjectPtr<UObject>:FSoftObjectProperty    注1:FSoftObjectPath的类型为FStructProperty   注2:FSoftObjectPtr不能作为属性

TSoftClassPtr<UObject>:FSoftClassProperty      注:FSoftClassPath的类型为FStructProperty

 

 

 

语言修饰符

结构体说明符

https://docs.unrealengine.com/zh-CN/ProgrammingAndScripting/GameplayArchitecture/Structs/Specifiers/index.html

 

类说明符

https://docs.unrealengine.com/zh-CN/ProgrammingAndScripting/GameplayArchitecture/Classes/#%E7%B1%BB%E8%AF%B4%E6%98%8E%E7%AC%A6

https://docs.unrealengine.com/zh-CN/ProgrammingAndScripting/GameplayArchitecture/Classes/Specifiers/index.html 

 

接口说明符

https://docs.unrealengine.com/zh-CN/ProgrammingAndScripting/GameplayArchitecture/Interfaces/#%E6%8E%A5%E5%8F%A3%E8%AF%B4%E6%98%8E%E7%AC%A6

 

函数说明符

https://docs.unrealengine.com/zh-CN/ProgrammingAndScripting/GameplayArchitecture/Functions/index.html

https://docs.unrealengine.com/zh-CN/ProgrammingAndScripting/GameplayArchitecture/Functions/Specifiers/index.html

 

属性说明符

https://docs.unrealengine.com/zh-CN/ProgrammingAndScripting/GameplayArchitecture/Properties/Specifiers/index.html

 

元数据UMetaData

UMetaData虽然在UPackage中,但是UField对其做了封装,并提供了GetMetaData的接口。

UMetaData通过TMap< FWeakObjectPtr, TMap<FName, FString> > ObjectMetaDataMap来存放Object的键值对信息

 

UENUM元数据

UENUM(meta=(ScriptName="EnvDirectionType"))
namespace EEnvDirection
{
    enum Type
    {
        TwoPoints    UMETA(DisplayName="Two Points",ToolTip="Direction from location of one context to another."),
        Rotation    UMETA(ToolTip="Context's rotation will be used as a direction."),
    };
}

 

USTRUCT元数据

USTRUCT(meta=(DisplayName="Static Mesh Control", Category="Controls", ShowVariableNameInTitle))
struct CONTROLRIG_API FRigUnit_Control_StaticMesh : public FRigUnit_Control
{
    GENERATED_BODY()

    FRigUnit_Control_StaticMesh();

    RIGVM_METHOD()
    virtual void Execute(const FRigUnitContext& Context) override;

    /** The the transform the mesh will be rendered with (applied on top of the control's transform in the viewport) */ UPROPERTY(meta=(Input))
    FTransform MeshTransform;
};

 

UCLASS元数据

UCLASS(BlueprintType, meta=(DisplayName="Empty Comp Shot", ShortTooltip="A simple base actor used to composite multiple render layers together."))
class COMPOSURE_API ACompositingElement : public AComposurePipelineBaseActor, public ICompImageColorPickerInterface
{
    GENERATED_UCLASS_BODY()

    // ... ...

protected:
    /*********************************/
    // Pipeline Passes 
    //   - protected to prevent users from directly modifying these lists (use the accessor functions instead)
 UPROPERTY(EditAnywhere, Instanced, BlueprintReadOnly, BlueprintGetter = GetInputsList, Category = "Composure|Input", meta=(ShowOnlyInnerProperties))
    TArray<UCompositingElementInput*> Inputs;

    UPROPERTY(EditAnywhere, Instanced, BlueprintReadOnly, BlueprintGetter = GetTransformsList, Category = "Composure|Transform/Compositing Passes", meta=(DisplayName = "Transform Passes", ShowOnlyInnerProperties, DisplayAfter="Inputs"))
    TArray<UCompositingElementTransform*> TransformPasses;

    UPROPERTY(EditAnywhere, Instanced, BlueprintReadOnly, BlueprintGetter = GetOutputsList, Category = "Composure|Output", meta = (ShowOnlyInnerProperties))
    TArray<UCompositingElementOutput*> Outputs;

    // ... ...

public:
    
    // ... ...

    /*********************************/
    // Pass Management 
 UFUNCTION(BlueprintCallable, Category = "Composure", meta = (DeterminesOutputType = "InputType"))
    UCompositingElementInput* FindInputPass(UPARAM(meta = (AllowAbstract = "false"))TSubclassOf<UCompositingElementInput> InputType, UTexture*& PassResult, FName OptionalPassName = NAME_None);
    UFUNCTION(BlueprintCallable, Category = "Composure", meta = (DeterminesOutputType = "TransformType"))
    UCompositingElementTransform* FindTransformPass(UPARAM(meta = (AllowAbstract = "false"))TSubclassOf<UCompositingElementTransform> TransformType, UTexture*& PassResult, FName OptionalPassName = NAME_None);
    UFUNCTION(BlueprintCallable, Category = "Composure", meta = (DeterminesOutputType = "OutputType"))
    UCompositingElementOutput* FindOutputPass(UPARAM(meta = (AllowAbstract = "false"))TSubclassOf<UCompositingElementOutput> OutputType, FName OptionalPassName = NAME_None);
    
    // ... ...
    
};

 

UINTERFACE元数据

UINTERFACE(MinimalAPI, meta=(CannotImplementInterfaceInBlueprint))
class UNavRelevantInterface : public UInterface
{
    GENERATED_UINTERFACE_BODY()  // 使用该宏,需要在cpp中实现UNamedSlotInterface::UNamedSlotInterface(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer) {}构造函数
};

class INavRelevantInterface
{
    GENERATED_IINTERFACE_BODY()

    /** Prepare navigation modifiers */
    virtual void GetNavigationData(FNavigationRelevantData& Data) const {}

    /** Get bounds for navigation octree */
    virtual FBox GetNavigationBounds() const { return FBox(ForceInit); }

    // ... ...
};

 

可通过命令Metadata.Dump来Dump所有的元信息到日志中

[2021.04.23-06.51.36:018][744]LogMetaData: METADATA /Script/CoreUObject.PackageMetaData
[2021.04.23-06.51.36:018][744]LogMetaData: /Script/CoreUObject.JoinabilitySettings: Comment=// Circular dependency on Core vs UHT means we have to noexport these structs so tools can build

[2021.04.23-06.51.36:018][744]LogMetaData: /Script/CoreUObject.JoinabilitySettings: ModuleRelativePath=Public/UObject/CoreOnline.h
[2021.04.23-06.51.36:018][744]LogMetaData: /Script/CoreUObject.UniqueNetIdWrapper: ModuleRelativePath=Public/UObject/CoreOnline.h
[2021.04.23-06.51.36:018][744]LogMetaData: /Script/CoreUObject.Guid: BlueprintType=true
[2021.04.23-06.51.36:018][744]LogMetaData: /Script/CoreUObject.Guid: Comment=/** A globally unique identifier (mirrored from Guid.h) */
[2021.04.23-06.51.36:018][744]LogMetaData: /Script/CoreUObject.Guid: ModuleRelativePath=Public/UObject/NoExportTypes.h
[2021.04.23-06.51.36:018][744]LogMetaData: /Script/CoreUObject.Vector: BlueprintType=true
[2021.04.23-06.51.36:018][744]LogMetaData: /Script/CoreUObject.Vector: Comment=/**
 * A point or direction FVector in 3d space.
 * @note The full C++ class is located here: Engine\Source\Runtime\Core\Public\Math\Vector.h
 */
[2021.04.23-06.51.36:018][744]LogMetaData: /Script/CoreUObject.Vector: HasNativeBreak=Engine.KismetMathLibrary.BreakVector
[2021.04.23-06.51.36:018][744]LogMetaData: /Script/CoreUObject.Vector: HasNativeMake=Engine.KismetMathLibrary.MakeVector
[2021.04.23-06.51.36:018][744]LogMetaData: /Script/CoreUObject.Vector: ModuleRelativePath=Public/UObject/NoExportTypes.h
[2021.04.23-06.51.36:018][744]LogMetaData: /Script/CoreUObject.Vector4: BlueprintType=true

                 。。。 。。。
				 
[2021.04.23-06.51.37:464][744]LogMetaData: /Script/AITestSuite.TestPawnAction_CallFunction: IncludePath=Actions/TestPawnAction_CallFunction.h
[2021.04.23-06.51.37:464][744]LogMetaData: /Script/AITestSuite.TestPawnAction_CallFunction: ModuleRelativePath=Classes/Actions/TestPawnAction_CallFunction.h
[2021.04.23-06.51.37:464][744]LogMetaData: METADATA /Engine/EditorResources/SequenceRecorder/Countdown.PackageMetaData
[2021.04.23-06.51.37:464][744]LogMetaData: Root: PackageLocalizationNamespace=E807D18340E352E3392B57A9706DA988
[2021.04.23-06.51.37:464][744]LogMetaData: METADATA /Script/SequenceRecorderSections.PackageMetaData
[2021.04.23-06.51.37:464][744]LogMetaData: /Script/SequenceRecorderSections.MovieSceneParticleTrackSectionRecorder:OnTriggered: ModuleRelativePath=Public/MovieSceneParticleTrackSectionRecorder.h
[2021.04.23-06.51.37:464][744]LogMetaData: /Script/SequenceRecorderSections.MovieSceneParticleTrackSectionRecorder: IncludePath=MovieSceneParticleTrackSectionRecorder.h
[2021.04.23-06.51.37:464][744]LogMetaData: /Script/SequenceRecorderSections.MovieSceneParticleTrackSectionRecorder: IsBlueprintBase=false
[2021.04.23-06.51.37:464][744]LogMetaData: /Script/SequenceRecorderSections.MovieSceneParticleTrackSectionRecorder: ModuleRelativePath=Public/MovieSceneParticleTrackSectionRecorder.h
[2021.04.23-06.51.37:464][744]LogMetaData: /Script/SequenceRecorderSections.MovieSceneVisibilitySectionRecorderSettings: IncludePath=MovieSceneVisibilitySectionRecorderSettings.h
[2021.04.23-06.51.37:464][744]LogMetaData: /Script/SequenceRecorderSections.MovieSceneVisibilitySectionRecorderSettings: ModuleRelativePath=Public/MovieSceneVisibilitySectionRecorderSettings.h

 

obj classes  // 按继承关系打印出类型信息及被淘汰的UProperty

[2021.04.26-20.49.25:237][860]Object (40)
[2021.04.26-20.49.25:237][860]  。。。 。。。
[2021.04.26-20.49.25:676][860]  Field (48)
[2021.04.26-20.49.25:676][860]    Struct (176)
[2021.04.26-20.49.25:676][860]      ScriptStruct (192)
[2021.04.26-20.49.25:676][860]        UserDefinedStruct (264)
[2021.04.26-20.49.25:676][860]          AISenseBlueprintListener (264)
[2021.04.26-20.49.25:676][860]      Class (624)
[2021.04.26-20.49.25:677][860]        DynamicClass (752)
[2021.04.26-20.49.25:677][860]        LinkerPlaceholderClass (1064)
[2021.04.26-20.49.25:677][860]        BlueprintGeneratedClass (880)
[2021.04.26-20.49.25:677][860]          WidgetBlueprintGeneratedClass (944)
[2021.04.26-20.49.25:677][860]          AnimBlueprintGeneratedClass (1528)
[2021.04.26-20.49.25:677][860]      Function (224)
[2021.04.26-20.49.25:677][860]        DelegateFunction (224)
[2021.04.26-20.49.25:678][860]          SparseDelegateFunction (240)
[2021.04.26-20.49.25:678][860]        LinkerPlaceholderFunction (664)
[2021.04.26-20.49.25:678][860]    Enum (96)
[2021.04.26-20.49.25:678][860]      UserDefinedEnum (176)
[2021.04.26-20.49.25:678][860]    Property (112)
[2021.04.26-20.49.25:678][860]      EnumProperty (128)
[2021.04.26-20.49.25:678][860]      ArrayProperty (120)
[2021.04.26-20.49.25:679][860]      ObjectPropertyBase (120)
[2021.04.26-20.49.25:679][860]        ObjectProperty (120)
[2021.04.26-20.49.25:679][860]          ClassProperty (128)
[2021.04.26-20.49.25:679][860]        LazyObjectProperty (120)
[2021.04.26-20.49.25:679][860]        SoftObjectProperty (120)
[2021.04.26-20.49.25:679][860]          SoftClassProperty (128)
[2021.04.26-20.49.25:679][860]        WeakObjectProperty (120)
[2021.04.26-20.49.25:680][860]      BoolProperty (120)
[2021.04.26-20.49.25:680][860]      NumericProperty (112)
[2021.04.26-20.49.25:680][860]        ByteProperty (120)
[2021.04.26-20.49.25:680][860]        DoubleProperty (112)
[2021.04.26-20.49.25:680][860]        FloatProperty (112)
[2021.04.26-20.49.25:680][860]        IntProperty (112)
[2021.04.26-20.49.25:680][860]        Int8Property (112)
[2021.04.26-20.49.25:681][860]        Int16Property (112)
[2021.04.26-20.49.25:681][860]        Int64Property (112)
[2021.04.26-20.49.25:681][860]        UInt16Property (112)
[2021.04.26-20.49.25:681][860]        UInt32Property (112)
[2021.04.26-20.49.25:681][860]        UInt64Property (112)
[2021.04.26-20.49.25:681][860]      DelegateProperty (120)
[2021.04.26-20.49.25:681][860]      InterfaceProperty (120)
[2021.04.26-20.49.25:682][860]      MapProperty (152)
[2021.04.26-20.49.25:682][860]      MulticastDelegateProperty (120)
[2021.04.26-20.49.25:682][860]        MulticastInlineDelegateProperty (120)
[2021.04.26-20.49.25:682][860]        MulticastSparseDelegateProperty (120)
[2021.04.26-20.49.25:682][860]      NameProperty (112)
[2021.04.26-20.49.25:682][860]      SetProperty (144)
[2021.04.26-20.49.25:682][860]      StrProperty (112)
[2021.04.26-20.49.25:683][860]      StructProperty (120)
[2021.04.26-20.49.25:683][860]      TextProperty (112)

                                    。。。 。。。

 

枚举元数据UMetaData说明符

https://docs.unrealengine.com/zh-CN/ProgrammingAndScripting/GameplayArchitecture/Metadata/#%E5%88%97%E4%B8%BE%E5%85%83%E6%95%B0%E6%8D%AE%E8%AF%B4%E6%98%8E%E7%AC%A6

 

结构体元数据UMetaData说明符

https://docs.unrealengine.com/zh-CN/ProgrammingAndScripting/GameplayArchitecture/Metadata/#%E7%BB%93%E6%9E%84%E4%BD%93%E5%85%83%E6%95%B0%E6%8D%AE%E8%AF%B4%E6%98%8E%E7%AC%A6

https://docs.unrealengine.com/zh-CN/ProgrammingAndScripting/GameplayArchitecture/Structs/Specifiers/#%E5%85%83%E6%95%B0%E6%8D%AE%E8%AF%B4%E6%98%8E%E7%AC%A6

 

类元数据UMetaData说明符

https://docs.unrealengine.com/zh-CN/ProgrammingAndScripting/GameplayArchitecture/Metadata/#%E7%B1%BB%E5%85%83%E6%95%B0%E6%8D%AE%E8%AF%B4%E6%98%8E%E7%AC%A6

https://docs.unrealengine.com/zh-CN/ProgrammingAndScripting/GameplayArchitecture/Classes/Specifiers/#%E5%85%83%E6%95%B0%E6%8D%AE%E8%AF%B4%E6%98%8E%E7%AC%A6

 

接口元数据UMetaData说明符

https://docs.unrealengine.com/zh-CN/ProgrammingAndScripting/GameplayArchitecture/Metadata/#%E6%8E%A5%E5%8F%A3%E5%85%83%E6%95%B0%E6%8D%AE%E8%AF%B4%E6%98%8E%E7%AC%A6

 

函数元数据UMetaData说明符

https://docs.unrealengine.com/zh-CN/ProgrammingAndScripting/GameplayArchitecture/Metadata/#%E5%87%BD%E6%95%B0%E5%85%83%E6%95%B0%E6%8D%AE%E8%AF%B4%E6%98%8E%E7%AC%A6

 

属性元数据UMetaData说明符

https://docs.unrealengine.com/zh-CN/ProgrammingAndScripting/GameplayArchitecture/Metadata/#%E5%B1%9E%E6%80%A7%E5%85%83%E6%95%B0%E6%8D%AE%E8%AF%B4%E6%98%8E%E7%AC%A6

https://docs.unrealengine.com/zh-CN/ProgrammingAndScripting/GameplayArchitecture/Properties/Specifiers/#%E5%85%83%E6%95%B0%E6%8D%AE%E8%AF%B4%E6%98%8E%E7%AC%A6

 

参考

《InsideUE4》UObject(二)类型系统概述

《InsideUE4》UObject(三)类型系统设定和结构

《InsideUE4》UObject(十二)类型系统-总结

《InsideUE4》UObject(十三)类型系统-反射实战

UFUNCTION/UPROPERTY/UCLASS

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM