在蓝图的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);