同步加载会造成进程阻塞。
在构造函数加载
ConstructorHelpers::FObjectFinder
ConstructorHelpers::FClassFinder
一般用来加载资源对象
UMaterial* M_Cube = LoadObject
if (M_Cube)
{
UE_LOG(LogTemp, Warning, TEXT("Material name:%s"), *M_Cube->GetName());
}
早期版本 StaticLoadObject()
,本处只作为记录,推荐使用 LoadObject
soundCue = Cast
UGameplayStatics::PlaySoundAtLocation(this, soundCue,SweepResult.Location);
一般用来加载蓝图类, UClass*
蓝图类的路径末尾加上_C
UClass* pClass = LoadClass
if (pClass)
{
UE_LOG(LogTemp, Warning, TEXT("pClass name:%s"), *pClass->GetName());
}
TSubclassOf
if (BPClass)
{
UE_LOG(LogTemp, Warning, TEXT("BPClass name:%s"), *BPClass->GetName());
}
配合 FSoftObjectPath 使用
TryLoad 中调用 LoadObject,加载时需要调用Cast转换一下
FSoftObjectPath SoftObjectPaths_Mesh = FSoftObjectPath(TEXT("StaticMesh'/Game/CPPFunction/Load/StaticMesh.StaticMesh'"));
UStaticMesh* Mesh1 = Cast
if (Mesh1)
{
UE_LOG(LogTemp, Warning, TEXT("Mesh1 name:%s"), *Mesh1->GetName());
}
搭配 FSoftClassPath 使用
TryLoadClass 中调用了 LoadClass
FSoftClassPath SoftClassPath_Actor = FSoftClassPath(TEXT("Blueprint'/Game/CPPFunction/Load/BP_MyActor_SoftRef.BP_MyActor_SoftRef_C'"));
UClass* pClass_Actor = SoftClassPath_Actor.TryLoadClass
if (pClass_Actor)
{
UE_LOG(LogTemp, Warning, TEXT("pClass_Actor name:%s"), *pClass_Actor->GetName());
}
FStreamableManager::内部调用 RequestSyncLoad
参数中返回一个FStreamableHandle类型的指针
配合FStreamableManager、FSoftObjectPath 使用
配合FStreamableManager、TSoftObjectPtr使用
// 配合 FSoftObjectPath 使用 方法一
FSoftObjectPath SoftObjectPaths_Mesh1 = FSoftObjectPath(TEXT("StaticMesh'/Game/CPPFunction/Load/StaticMesh.StaticMesh'"));
UStaticMesh* StaticMesh1 = UAssetManager::GetStreamableManager().LoadSynchronous
if (StaticMesh1)
{
UE_LOG(LogTemp, Warning, TEXT("Mesh1 name:%s"), *StaticMesh1->GetName());
}
// 配合 FSoftObjectPath 使用 方法二
FStreamableManager& streamableManager = UAssetManager::GetStreamableManager();
FSoftObjectPath SoftObjectPaths_Mesh2 = FSoftObjectPath(TEXT("StaticMesh'/Game/CPPFunction/Load/StaticMesh_Soft.StaticMesh_Soft'"));
UStaticMesh* StaticMesh2 = streamableManager.LoadSynchronous
if (StaticMesh2)
{
UE_LOG(LogTemp, Warning, TEXT("Mesh2 name:%s"), *StaticMesh2->GetName());
}
// 配合 TSoftObjectPtr
FSoftObjectPath SoftObjectPaths_Mesh3 = FSoftObjectPath(TEXT("StaticMesh'/Game/CPPFunction/Load/StaticMesh_Soft2.StaticMesh_Soft2'"));
TSoftObjectPtr
UStaticMesh* StaticMesh3 = streamableManager.LoadSynchronous(SoftObjectPtr_Mesh);//保持良好习惯
if (StaticMesh3)
{
UE_LOG(LogTemp, Warning, TEXT("Mesh3 name:%s"), *StaticMesh3->GetName());
}
配合FStreamableManager、TSoftObjectPtr使用
配合FStreamableManager、TSoftClassPtr使用
FSoftObjectPath SoftObjectPaths_Actor1 = FSoftObjectPath(TEXT("Blueprint'/Game/CPPFunction/Load/BP_MyActor.BP_MyActor_C'"));
UClass* BPClass1 = UAssetManager::GetStreamableManager().LoadSynchronous
if (BPClass1)
{
UE_LOG(LogTemp, Warning, TEXT("BPClass1 name:%s"), *BPClass1->GetName());
}
// 配合 FSoftObjectPath 使用 方法二
FStreamableManager& streamableManager = UAssetManager::GetStreamableManager();
FSoftObjectPath SoftObjectPaths_Actor2 = FSoftObjectPath(TEXT("Blueprint'/Game/CPPFunction/Load/BP_MyActor_SoftRef.BP_MyActor_SoftRef_C'"));
UClass* BPClass2 = streamableManager.LoadSynchronous
if (BPClass2)
{
UE_LOG(LogTemp, Warning, TEXT("BPClass2 name:%s"), *BPClass2->GetName());
}
// 配合 TSoftObjectPtr
FSoftObjectPath SoftObjectPaths_Actor3 = FSoftObjectPath(TEXT("Blueprint'/Game/CPPFunction/Load/BP_MyActor_SoftRef2.BP_MyActor_SoftRef2_C'"));
TSoftObjectPtr
UClass* BPClass3 = streamableManager.LoadSynchronous(SoftObjectPtr_Actor); //保持良好习惯可添加
if (BPClass3)
{
UE_LOG(LogTemp, Warning, TEXT("BPClass3 name:%s"), *BPClass3->GetName());
}
配合 FStreamableManager、FSoftObjectPath 使用
返回一个FStreamableHandle类型的指针
TSharedPtr 通过 GetLoadedAsset() 获取单个资源
TSharedPtr 通过 GetLoadedAssets() 获取多个资源
// 获取单个资源 方法一
FSoftObjectPath SoftObjectPaths_Mesh1 = FSoftObjectPath(TEXT("StaticMesh'/Game/CPPFunction/Load/StaticMesh.StaticMesh'"));
TSharedPtr
if (Handle1.IsValid())
{
UStaticMesh* StaticMesh1 = Cast
UE_LOG(LogTemp, Warning, TEXT("Mesh1 name:%s"), *StaticMesh1->GetName());
}
// 获取单个资源 方法二
FStreamableManager& streamableManager = UAssetManager::GetStreamableManager();
FSoftObjectPath SoftObjectPaths_Mesh2 = FSoftObjectPath(TEXT("StaticMesh'/Game/CPPFunction/Load/StaticMesh_Soft.StaticMesh_Soft'"));
TSharedPtr
if (Handle2.IsValid())
{
UStaticMesh* StaticMesh2 = Cast
UE_LOG(LogTemp, Warning, TEXT("Mesh1 name:%s"), *StaticMesh2->GetName());
}
// 获取多个资源
TArray
SoftObjectPaths.Add(SoftObjectPaths_Mesh1);
SoftObjectPaths.Add(SoftObjectPaths_Mesh2);
TSharedPtr
{
TArray
UE_LOG(LogTemp, Warning, TEXT("GetLoadedAssets(), item name:%s"), *StaticMesh3->GetName());
}
}
为了避免阻塞主线程,可以使用异步加载的方式来加载资源
异步加载完成后,可以设置回调函数
创建 FStreamableManager
,建议将它放在某类全局游戏单件对象中,如使用GameSingletonClassName
在 DefaultEngine.ini
中指定的对象
返回一个 FStreamableHandle 类型的指针
单文件加载
UPROPERTY(EditAnywhere, Category = "SoftObjectPath", meta = (AllowedClasses = "StaticMesh"))
FSoftObjectPath SingeleObject;
UFUNCTION()
void OnSingleAssetLoadFinshed();
// 函数内部分语句
FStreamableManager& streamableManager = UAssetManager::GetStreamableManager();
FStreamableDelegate streamableDelegate = FStreamableDelegate::CreateUObject(this, &ALoadActor::OnSingleAssetLoadFinshed);
streamableManager.RequestAsyncLoad(SingeleObject, streamableDelegate);
// 要回调的函数
void ALoadActor::OnSingleAssetLoadFinshed()
{
FSoftObjectPtr SoftObjPtr = FSoftObjectPtr(SingeleObject);
UStaticMesh* mesh = Cast<UStaticMesh>(SoftObjPtr.Get());
if (mesh)
{
UE_LOG(LogTemp, Warning, TEXT("mesh name:%s"), *mesh->GetName());
}
}
多文件加载
方法一 配合 FSoftObjectPtr
FSoftObjectPtr是一个结构体,是一种指向UObject的弱指针。无法在蓝图中使用
TSoftObjectPtr是一个模板类,是通用FSoftObjectPtr的模块化包装器
UPROPERTY(EditAnywhere, Category="SoftObjectPath", meta = (AllowedClasses = "StaticMesh"))
TArray
UFUNCTION()
void OnMultiAssetsLoadFinshed1();
// 函数内部分语句
FStreamableManager& streamableManager = UAssetManager::GetStreamableManager();
FStreamableDelegate streamableDelegate = FStreamableDelegate::CreateUObject(this, &ALoadActor::OnMultiAssetsLoadFinshed1);
streamableManager.RequestAsyncLoad(ObjectList1, streamableDelegate);
// 要回调的函数
void ALoadActor::OnMultiAssetsLoadFinshed1()
{
for (auto AssetItem : ObjectList1)
{
FSoftObjectPtr SoftObjPtr = FSoftObjectPtr(AssetItem); //此处也可用 TSoftObjectPtr
UStaticMesh* mesh = Cast
if (mesh)
{
UE_LOG(LogTemp, Warning, TEXT("mesh name:%s"), *mesh->GetName());
}
}
}
方法二 配合TSoftObjectPtr<T>
UPROPERTY(EditAnywhere, Category = "SoftObjectPath")
TArray<TSoftObjectPtr<UTexture2D>> ObjectList2;
UFUNCTION()
void OnMultiAssetsLoadFinshed2();
// 函数内部分语句
FStreamableManager& streamableManager = UAssetManager::GetStreamableManager();
FStreamableDelegate streamableDelegate;
streamableDelegate.BindUObject(this, &ALoadActor::OnMultiAssetsLoadFinshed2);
TArray<FSoftObjectPath> SoftPathList;
for (int32 i=0; i<ObjectList2.Num(); i++)
{
SoftPathList.Add(ObjectList2[i].ToSoftObjectPath());
}
streamableManager.RequestAsyncLoad(SoftPathList, streamableDelegate);
// 要回调的函数
void ALoadActor::OnMultiAssetsLoadFinshed2()
{
for (auto AssetItem : ObjectList2)
{
UTexture2D* ItemTex = AssetItem.Get();
if (ItemTex)
{
UE_LOG(LogTemp, Warning, TEXT("Texture2D name:%s"), *ItemTex->GetName());
}
}
}
单文件加载 FSoftClassPath 、TSoftClassPtr
测试 TArray<FSoftClassPath>
加载多个蓝图类编译不通过
UPROPERTY(EditAnywhere, Category = "SoftClassPath", meta = (MetaClass = "Actor"))
FSoftClassPath SingleClassPath;
UFUNCTION()
void OnSingleClassLoadFinshed();
// 函数内部分语句
FStreamableManager& streamableManager = UAssetManager::GetStreamableManager();
FStreamableDelegate streamableDelegate = FStreamableDelegate::CreateUObject(this, &ALoadActor::OnSingleClassLoadFinshed);
streamableManager.RequestAsyncLoad(SingleClassPath, streamableDelegate);
// 函数内部分语句
void ALoadActor::OnSingleClassLoadFinshed()
{
TSoftClassPtr
UClass* ItemClass = ItemPtr.Get();
if (ItemClass)
{
UE_LOG(LogTemp, Warning, TEXT("Actor name:%s"), *ItemClass->GetName());
}
}
ForceGC
可销毁对象LoadSynchronous()、RequestSyncLoad()、RequestAsyncLoad() 默认bManageActiveHandle 参数为false,表示自动管理内存;当设为true,表示常驻内存直到手动释放
FStreamableManager::Unload()会Release掉和当前资源相关的所有FStreamableHandle
编辑器模式下会一直常驻内存,打包版本中才会生效
FStreamableManager& streamableManager = UAssetManager::GetStreamableManager();
streamableManager.Unload(FSoftObjectPath(AssetPath));
//需要立即回收的话
GEngine->ForceGarbageCollection(true);
//GetWorld()->ForceGarbageCollection(true);
异步加载时,如果资源还没加载完成就执行ReleaseHandle()(假设加载时bManageActiveHandle为true),比如在执行回调函数之前执行ReleaseHandle,那么当资源加载完成后(回调函数执行之后),会自动从内存中回收。不过该对象在回调函数中仍然有效,除非在回调函数内ForceGC。
编辑器模式下会一直常驻内存,打包版本中才会生效
TSharedPtr
Handle1->ReleaseHandle();
编辑器模式下卸载后,对象从内存中销毁,无法再次Load,需要重启编辑器
UMaterial* M_Cube = LoadObject
if (M_Cube)
{
M_Cube->ConditionalBeginDestroy();
M_Cube = nullptr;
GetWorld()->ForceGarbageCollection();
}
手机扫一扫
移动阅读更方便
你可能感兴趣的文章