【UE4】加載資源的方式(五)使用ObjectLibrary引用然后加載
參考資料&原文鏈接
(UE4 4.20)UE4同步加載和異步加載UObject ----------LoadObject,LoadClass,FStreamableManager
UObjectLibrary
ObjectLibrary:是一個對象,包含了一系列繼承共享基類的未加載對象或者未加載對象的FAssetData 。您可以通過提供一個搜索路徑來加載一個對象庫,它將加載那個路徑中的所有資源。
發現了吧,里面放的就是一個FAssetData
:
/** Asset data of objects that will belong in library, possibly not loaded yet */
TArray<FAssetData> AssetDataList;
只不過與FAssetData
不同的是FAssetData
需要我們手動添加路徑,而這個我們只需要給它設定一個路徑,然后讓它來掃描,那么就不用我們手動來一個一添加了,會為我們省很多事。
CreateLibrary
函數介紹:
/**
* Static function to create a new ObjectLibrary at runtime, with various options set
* There is now a better version of this functionality in AssetManager, if you are creating many game-specific libraries you should switch to using AssetManager instead
* @param InBaseClass Only objects of this class can exist in the library
* @param bInHasBlueprintClasses If true, this library contains blueprint classes derived from BaseClass, will convert them correctly
* @param InUseWeak If true, references to objects are weak, so they can be garbage collected. Useful in the editor to allow deletion
*/
ENGINE_API static class UObjectLibrary* CreateLibrary(UClass* InBaseClass, bool bInHasBlueprintClasses, bool bInUseWeak);
靜態函數在運行時創建新的ObjectLibrary,並設置各種選項。參數介紹:
現在在AssetManager中有一個更好的版本,如果你正在創建許多游戲特定的庫,你應該轉而使用AssetManager。
InBaseClass
只有該類的對象才能存在於庫中。
bInHasBlueprintClasses
如果為true,則該庫包含從BaseClass派生的藍圖類,將正確地轉換它們
InUseWeak
如果為true,則對對象的引用為弱引用,因此可以對它們進行垃圾回收。在編輯器中用於允許刪除。
注意:最好不要讓ObjectLibrary給GC回收掉,所以可以添加到根節點,因為你不想還在掃描或者加載的途中出什么岔子。
掃描好之后可以用GetAssetDataList
來獲取掃描的結果,傳入一個TArray<FAssetData>
的引用來獲得所有的路徑,這個路徑就是傳入掃描的路徑,然后可以按需加載,可以說是相當方便了,拿到資源后引用后再加載即可。
/** Returns the list of asset data */
virtual void GetAssetDataList(TArray<FAssetData>& OutAssetData);
附上完整代碼:
//.h
private:
int32 CurrentCount = 0;
UObjectLibrary* TextureOL;
TArray<FAssetData> TextureData;
TArray<FSoftObjectPath> TexturePath;
//.cpp
void UWC_TestUI::NativeConstruct()
{
Super::NativeConstruct();
//如果UObjectLibrary未被加載
if (!TextureOL)
{
//加茲一手,類型寫自己想要的
TextureOL = UObjectLibrary::CreateLibrary(UTexture2D::StaticClass(), false, false);
//手動指定不要被GC回收
TextureOL->AddToRoot();
}
//掃描路徑
TextureOL->LoadAssetDataFromPath("/Game/UI/Images");
}
void UWC_TestUI::OnBtnClickCommonBtn_OL()
{
//沒有數據就先拿數據
if(TexturePath.Num() <= 0)
{
//拿到資產列表,注意這里的TextureData傳遞的是一個引用
TextureOL->GetAssetDataList(TextureData);
for (int32 i = 0; i < TextureData.Num(); ++i)
{
//保存了TextureData的所有ToSoftObjectPath
TexturePath.AddUnique(TextureData[i].ToSoftObjectPath());
}
}
//有數據就填充列表
if (TexturePath.Num() > 0)
{
FString ImgSAR = TexturePath[CurrentCount].ToString();
Img_OL->SetBrushFromTexture(LoadObject<UTexture2D>(nullptr,*ImgSAR));
if (CurrentCount >= TexturePath.Num() - 1)
{
CurrentCount = 0;
}
else {
CurrentCount++;
}
}
}
並且還可以根據名稱來拿到我想要的資源,詳情見:官方文檔 - 異步資源加載。
其他函數
//返回Object的數量
/** Returns the number of objects */
int32 GetObjectCount() const;
//這里還有個方法是:int32 GetAssetDataCount() const
//返回資產數據列表
/** Returns the list of asset data */
virtual void GetAssetDataList(TArray<FAssetData>& OutAssetData);
//將整個資源子目錄加載到這個對象庫中。返回加載的資產數量
/** Load an entire subdirectory of assets into this object library. Returns number of assets loaded */
virtual int32 LoadAssetsFromPaths(const TArray<FString>& Paths);
//獲取子目錄中的資產的資產數據。返回加載的資產數據的數量
/** Gets asset data for assets in a subdirectory. Returns number of assets data loaded */
virtual int32 LoadAssetDataFromPaths(const TArray<FString>& Paths, bool bForceSynchronousScan = true);
virtual int32 LoadAssetDataFromPath(const FString& Path);
特點
- 其內部只是一個DataAsset而已,只不過不一樣的是我們不需要自定義數據結構來記錄資產路徑,而是需要給它一個掃描路徑和掃描類型,那么它就會幫我們記錄,就不用我們一個一個手動的添加了。
- 同樣的,他也只是記錄路徑,加載是靠其他方法。當然你要是想用它自帶的方法加載也不是不行。
本文標簽
游戲開發
、游戲開發基礎
、Unreal Engine
、UE資源加載
。