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