[UE4]C++靜態加載問題:ConstructorHelpers::FClassFinder()和FObjectFinder()

相關內容:

C++實現動態加載的問題:LoadClass<T>()和LoadObject<T>() 

http://aigo.iteye.com/blog/2281558
C++實現動態加載UObject:StaticLoadObject();以Texture和Material爲例

http://aigo.iteye.com/blog/2268056

 

這裏說的靜態加載指的是必須在構造函數中完成的加載方式,動態加載值得是可以在Runtime期間加載的方式,UE4源碼裏面,前者其實是對後者的一層封裝,即FObjectFinder()是對LoadObject()的封裝。But,FClassFinder()不是對LoadClass()的封裝,FClassFinder()內部調用的是LoadObject()。

 

 

如果要獲取某個藍圖BP的類型class,可以通過ConstructorHelpers::FClassFinder()來獲取,例如:

Cpp代碼 

 收藏代碼

  1. static ConstructorHelpers::FClassFinder<AActor> UnitSelector(TEXT("Blueprint'/Game/MyProject/MyBlueprint.MyBlueprint'"));  
  2. TSubclassOf<AActor> UnitSelectorClass = UnitSelector.Class;  

 
但是在啓動遊戲時會報錯提示找不到文件,例如:

 

Default property warnings and errors:

Error: COD Constructor (MyGameMode): Failed to find /Game/MyProject/MyBlueprint.MyBlueprint

 

解決辦法有兩種(這是UE4的一個坑,浪費了我很長時間。。。):

A,在copy reference出來的文件路徑後面加_C,例如:Blueprint'/Game/Blueprints/MyBlueprint.MyBlueprint_C'
 

Cpp代碼 

 收藏代碼

  1. static ConstructorHelpers::FClassFinder<AActor> UnitSelector(TEXT("Blueprint'/Game/Blueprints/MyBlueprint.MyBlueprint_C'"));  
  2. TSubclassOf<AActor> UnitSelectorClass = UnitSelector.Class;  

   

B,去掉路徑前綴:/Game/Blueprints/MyBlueprint

 

Cpp代碼 

 收藏代碼

  1. static ConstructorHelpers::FClassFinder<AActor> UnitSelector(TEXT("/Game/Blueprints/MyBlueprint"));  
  2. TSubclassOf<AActor> UnitSelectorClass = UnitSelector.Class;  

 

另外注意:FClassFinder<T>的模版名稱,不能直接寫UBlueprint,例如:FClassFinder<UBlueprint>是錯誤的。創建藍圖時選擇的是什麼父類,則寫對應的父類名,假如是Actor,那麼要寫成:FClassFinder<AActor>,否則無法加載成功。

 

 

使用TSubclassOf<T>時模板名必須相同

另外, FClassFinder<T>()函數中的模版名必須和TSubclassOf<T>變量的模版名一樣,例如上面的都是AActor,如果不一樣,也會出現上面的錯誤。
再給個例子:

Cpp代碼 

 收藏代碼

  1. static ConstructorHelpers::FClassFinder<UUserWidget> TestBP(TEXT("/Game/Blueprints/MyWidget_BP"));  
  2. TSubclassOf<UUserWidget> MyWidgetClass = TestBP.Class;  

 

也可使用UClass*替換TSubclassOf<T>

例如:

Cpp代碼 

 收藏代碼

  1. static ConstructorHelpers::FClassFinder<UUserWidget> TestBP(TEXT("/Game/Blueprints/MyWidget_BP"));  
  2. UClass* MyWidgetClass = TestBP.Class;  

 

 

之前看到很多例子是通過FObjectFinder()來獲取class,現在想想感覺是無奈之舉,UE4的文檔比較坑,不僅藍圖的文檔更新不同步,C++的文檔更是少得可憐。

Cpp代碼 

 收藏代碼

  1. static ConstructorHelpers::FObjectFinder<UBlueprint> UnitSelector(TEXT("Blueprint'/Game/MyProject/MyBlueprint.MyBlueprint'"));  
  2. TSubclassOf<AActor> UnitSelectorClass = (UClass*)UnitSelector.Object->GeneratedClass;  

 

 

 

其他參考:

CDO Constructor: Failed to find Blueprint

https://answers.unrealengine.com/questions/84880/cdo-constructor-failed-to-find-blueprint-ue-44.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章