在編譯之前,通過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
② UStruct為UScriptStruct、UFunction、UClass的基類,統一提供了對屬性的支持;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
語言修飾符
結構體說明符
類說明符
接口說明符
函數說明符
屬性說明符
元數據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說明符
結構體元數據UMetaData說明符
類元數據UMetaData說明符
接口元數據UMetaData說明符
函數元數據UMetaData說明符
屬性元數據UMetaData說明符
參考
《InsideUE4》UObject(三)類型系統設定和結構
《InsideUE4》UObject(十三)類型系統-反射實戰