1 UPROPERTY 使用 在Unreal Engine 4中,所有UObject实例都被垃圾回收系统管理。这意味着,如果没有任何强引用指向UObject实例,那么这个实例可能在任何时候被垃圾回收系统销毁。 强引用包括:在另一个UObject实例中的UPROPERTY指向它,或者在代码中有一个持有该实例的TArray、TMap、TSet、或UObject指针等其他强引用容器。 在你的情况下,你的管理类有一个TMap用来存储UObject实例。然而,这个TMap并不是UPROPERTY,所以它不被视为强引用。这就可能导致垃圾回收系统在任何时候销毁存储在TMap中的UObject实例,从而使TMap中的指针过时。 为了解决这个问题,你应该将你的TMap声明为UPROPERTY,这样垃圾回收系统就会知道这些UObject实例正在被使用,因此不会销毁它们: ```cpp UCLASS() class BOSI_API UXMLSubsystem : public UGameInstanceSubsystem { GENERATED_BODY() public: UPROPERTY() TMap<FString, UXMLConfig*> MapForConfigData; // 你的其他代码 }; ``` 这样,只要你的管理类实例存在,垃圾回收系统就不会销毁存储在MapForConfigData中的UObject实例。 # 模板条件编译 2. `if constexpr`是C++17引入的一种条件编译指令。它允许在编译时根据常量表达式的值决定是否编译某段代码。在你的代码中,`TIsDerivedFrom<T, UMyConfigDataBase>::IsDerived`是一个编译时常量表达式,它会检查`T`是否是`UMyConfigDataBase`的派生类。如果`T`是`UMyConfigDataBase`的派生类,那么这个表达式的值为`true`,编译器将会编译`if constexpr`内部的代码。如果`T`不是`UMyConfigDataBase`的派生类,那么这个表达式的值为`false`,编译器将不会编译`if constexpr`内部的代码。这就允许你在模板函数中添加特定于某些类型的代码,而不会影响其他类型。 # 3 UFUNCTION 这个错误信息是在尝试绑定一个名为'Button1Click'的委托(Delegate)时发生的,特别是在初始化你的UHOME_UI用户界面时。错误信息的主要部分是: ``` LogOutputDevice: Error: Unable to bind delegate to 'Button1Click' (function might not be marked as a UFUNCTION or object may be pending kill) ``` 这表明在试图将函数'Button1Click'绑定到一个委托时出现了问题。错误信息中给出了两种可能的原因: 1. 'Button1Click'可能没有被标记为UFUNCTION。在Unreal Engine 4中,任何需要被蓝图调用,或者需要作为事件处理器(如点击事件)的函数,都需要使用UFUNCTION宏进行标记。如果你没有这么做,UE4的反射系统将无法识别这个函数,从而无法将其绑定到委托。 2. 被引用的对象可能正在等待销毁(Pending Kill)。如果一个对象正在等待销毁,那么你将无法将其上的函数绑定到委托。这通常发生在一个对象被标记为销毁,但实际的销毁操作还没有发生时。 为了解决这个问题,你可以检查'Button1Click'函数是否被正确标记为UFUNCTION,并确保试图绑定的对象没有被标记为销毁。你也可以检查你的UHOME_UI类的Initialize函数,以及任何与'Button1Click'相关的代码,看看是否存在其他可能的问题。 # 4 UEC++中使用嵌套类 在C++中,嵌套结构体(或类)声明在某些情况下是允许的。然而,Unreal Engine 4的UCLASS宏不支持嵌套类或结构体声明。如果你尝试在UCLASS内部声明USTRUCT,你将会得到编译错误。 你可以将结构体声明放在同一个头文件中,但是需要在类的外部。例如: ```cpp USTRUCT(BlueprintType) struct FPlayerConfigDataStruct { GENERATED_BODY() UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "PlayerConfigData") FString Name; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "PlayerConfigData") int32 Id; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "PlayerConfigData") int32 Hp; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "PlayerConfigData") int32 Mp; }; UCLASS() class UMyPlayerConfigData : public UMyConfigDataBase { GENERATED_BODY() public: //实现纯虚函数 virtual bool LoadDataWithXml(const FXmlNode* Node) override; UPROPERTY(EditAnywhere,BlueprintReadWrite,Category="PlayerConfigData") FPlayerConfigDataStruct PlayerData; }; ``` 这样,你的结构体和类在同一个头文件中,但是结构体并没有在类内部声明。