一.UObject的創建
UObject 不支持構造參數。
所有的C++ UObject都會在引擎啟動的時候初始化,然后引擎會調用其默認構造器。如果沒有默認的構造器,那么 UObject 將不會編譯。
有修改父類參數的需求,就使用指定帶參構造
// Sets default values for this actor's propertiesAMyActor();// AMyActor(const FObjectInitializer& ObjectInitializer);
創建
1.?NewObject<T>();
虛幻會管理,它重載了new 和 delete。
myObject = NewObject<UBaseObject>();
2.? ? ?CreateDefaultSubobject<T>();
RootComponent = CreateDefaultSubobject<USceneComponent>("Root");
只是上一個更通用,下面這個在構造函數里才使用,來創建和管理組件。
二.測試垃圾回收
在你Actor的頭文件的中,聲明一個UObject·。
UCLASS()
class MYPROJECT_API UBaseObject :public UObject
{GENERATED_BODY()
public:UBaseObject();UBaseObject(const FObjectInitializer& ObjectInitializer);virtual ~UBaseObject();int32 Health = 666;
};
并在Actor里聲明它。
public: // Called every framevirtual void Tick(float DeltaTime) override;UFUNCTION(BlueprintCallable)void InitBaseObject();UFUNCTION(BlueprintCallable)int32 GetBaseObjectHealth();//為了避免對象被回收//UPROPERTY() //有對象引用了,就不會被回收UBaseObject* myObject = nullptr;
};
CPP里實現
void AMyActor::InitBaseObject()
{myObject = NewObject<UBaseObject>();myObject->AddToRoot();
}int32 AMyActor::GetBaseObjectHealth()
{if (myObject){return myObject->Health;}return -1;
}UBaseObject::UBaseObject()
{UE_LOG(LogTemp, Warning, TEXT("初始化了"));}UBaseObject::UBaseObject(const FObjectInitializer& ObjectInitializer)
{UE_LOG(LogTemp, Warning, TEXT("初始化了2"));
}UBaseObject::~UBaseObject()
{UE_LOG(LogTemp, Warning, TEXT("垃圾回收"));
}
測試
一旦按下3,垃圾回收。自己的UObject就會被回收掉。
解決方案,加上UPOPERTY,讓它被對象引用。
//為了避免對象被回收UPROPERTY() //有對象引用了,就不會被回收UBaseObject* myObject = nullptr;
AddtoRoot,強制不被回收。和允許回收。少用這個方法。
void AMyActor::InitBaseObject()
{myObject = NewObject<UBaseObject>();myObject->AddToRoot();
}
注:標記UPROPERTY 會自動加入root set 阻止垃圾回收
一個Up標記object類指針變量,當指向null時,object會進行析構,自動進行垃圾回收
一個非標記的object類變量,當未添加AddToRoot時,會被下一次垃圾回收,留下野指針。
你通常需要保持對希望保持活躍的任何Object的`UPROPERTY`引用,或者將指向它的指針存儲在`TArray`或其他引擎容器類中。