UE4/5 中的TSoftObjectPtr<>、TSoftClassPtr<>和TSubclassOf<>

在蓝图的Actor变量类型中,有4中对象引用
在这里插入图片描述

分别创建这4个对象,然后拖到事件图标中,就可以知道它们有什么区别

在这里插入图片描述

对象引用:指一个对象实例的引用,硬引用。

类引用:指一个对象类型的引用,可自定义选择类对象,硬引用。

软对象引用:可自定义选择对象实例的引用,软引用。

软类引用:可自定义选择类对象类型,软引用。

硬引用

硬引用是指直接引用一个对象,即上面蓝图中的对象、类引用。
  • 硬引用在对象初始化时就加载进内存,一些暂时用不到的资源会占用内存;
  • 硬引用在对象初始化时就加载进内存,一些暂时用不到的资源会占用内存;
  • 大量的资源加载可能会阻塞进程,导致加载时间过长;

在C++中的硬引用,可以直接用对象指针,也可以用TSubclassOf<>指定类型。

UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "MyProperty")
AActor* lyAcotrOne://对象实例指针

UPROPERTY(EditAnywhere,BlueprintReadWrite, Category = "MyProperty")
TSubclass0f<AActor> MyAcotrTwo;//对象类型,允许使用类型安全传递UCass的模板

软引用

软引用是指通过间接机制(例如字符串形式的对象路径)来引用对象。
  • 软引用不会主动加载,只在使用时才会加载;
  • 可随时灵活加载,减小加载负担,缩短启动时间;
  • 需要手动加载(同步/异步);

在C++中的软引用,TSoftObjectPtr<>、TSoftClassPtr<>, 即上面蓝图中的软对象、类引用;

TSoftObjectPtr.IsPending() 方法可检查资源是否已准备好可供访问;

TSoftObjectPtr.Get() 如果被引用资源存在于内存中,将返回这个资源对象

UPROPERTY(EditAnywhere, BlueprintReadwWrite, Category = "MyProperty”)
TSoftObjectPtr<AActor> MyAcotrThree;//对象软引用,需要的时候加载

UPROPERTY(EditAnywhere, BlueprintReadwWrite, Category = "MyProperty”)
TSoftClassPtr<AActor> MAcotrFour, //对象类型软引用,需要的时候加载

TAssetPtr<>、FStringAssetReference,资源软引用,包含资源路径。

UPROPERTY(EditAnywhere,BlueprintReadWrite Category = "MyProperty")
TAssetPtr<AActor> MAssetOne; //资源引用,包含对象路径和弱指针

UPROPERTY(EditAnywhere, BlueprintReadWrite, meta=(MetaClass-"Actor"), Category = "MyProperty")
FStringAssetReference MyAssetTwo; //资源路径的引用,Meta限定对象属性

同步加载

同步加载有可能会造成进程阻塞,一般用于加载少量、较小的资源对象。

1.LoadObject():加载UObject,一般用来加载非蓝图资源。

UTexture2D* Texture2D = LoadObject<UTexture2D(nullptr,TEXT("Texture2D'/Game/Textures/tex1.tex1'"));

2.LoadClass():加载UClass,一般用来加载蓝图资源并获取蓝图Class,注意带后缀_C或去掉前缀。

TSubclassOf<AActor> BPClass = LoadClass<AActor>(nullptr, TEXT("/Game/Blueprints/MyBP"));

3.TryLoad():配合FSoftObjectPath使用,加载时需要调用Cast转换一下。

FSoftObjectPath Path_Mesh = FSoftObjectPath(TEXT("StaticMesh'/Game/Load/StaticMesh.StaticMesh'"));
UStaticMesh* Mesh = Cast<UStaticMesh>(Path_Mesh.TryLoad());

4.TryLoadClass():配合FSoftObjectPath使用,直接根据路径加载资源。

FSoftClassPath Path_Actor = FSoftClassPath(TEXT("Blueprint'/Game/Load/BP_MyActor.BP_MyActor_C'"));
UClass* pClass_Actor = Path_Actor.TryLoadClass<AActor>();

5.FStreamableManager::LoadSynchronous():配合FSoftObjectPath使用,也可配合TSoftObjectPtr使用。

// 配合 FSoftObjectPath 使用

FSoftObjectPath Path_Mesh1 = FSoftObjectPath(TEXT("StaticMesh'/Game/Load/StaticMesh.StaticMesh'"));
UStaticMesh* StaticMesh1 = UAssetManager::GetStreamableManager().LoadSynchronous<UStaticMesh>(Path_Mesh1);

// 配合 TSoftObjectPtr 使用

FSoftObjectPath Path_Mesh2 = FSoftObjectPath(TEXT("StaticMesh'/Game/Load/StaticMesh2.StaticMesh2'"));
TSoftObjectPtr<UStaticMesh> Ptr_Mesh = TSoftObjectPtr<UStaticMesh>(Path_Mesh2);
UStaticMesh* StaticMesh2 = UAssetManager::GetStreamableManager().LoadSynchronous(Ptr_Mesh);

异步加载

可避免阻塞主线程,可同时加载多个资源。

FStreamableManager::RequestAsyncLoad()

1.单文件加载

//1.单文件加载
UPROPERTY(EditAnywhere)
	FSoftObjectPath SingeleObject;
//加载完成后调用委托
UAssetManager::GetStreamableManager().RequestAsyncLoad(SingeleObject, FStreamableDelegate::CreateUObject(this, &ALoadActor::OnLoadFinshed));
// 要回调的函数
void ALoadActor::OnLoadFinshed()
{
    
    
	//do something
}

2.多文件加载

//2.多文件加载

UPROPERTY(EditAnywhere)
	TArray<FSoftObjectPath> ItemsToStream;
for(int32 i = 0; i < ItemList.Num(); ++i)
       ItemsToStream.AddUnique(ItemList[i].ToStringReference());
//根据一组软引用来异步加载一组资源,加载完后调用委托
UAssetManager::GetStreamableManager().RequestAsyncLoad(ItemsToStream, FStreamableDelegate::CreateUObject(this, &ALoadActor::OnLoadFinshed));

// 要回调的函数
void ALoadActor::OnLoadFinshed()
{
    
    
	//do something
}

卸载资源

1.自动回收

对象失去引用后会自动回收。

2.手动回收

FStreamableManager::Unload()可以Release掉和当前资源相关的所有FStreamableHandle;

UAssetManager::GetStreamableManager().Unload(FSoftObjectPath(AssetPath));

//需要立即回收的话
GetWorld()->ForceGarbageCollection(true);

猜你喜欢

转载自blog.csdn.net/weixin_41130251/article/details/131602636