UE4学习记录:资源加载(二) ——异步加载资源

上篇文章我们是用DataAsset记录资源的弱引用,这次我们用ObjectLibrary来获取资源路径,然后用StreamableManager异步加载资源。

ObjectLibrary:是一个对象,包含了一系列继承共享基类的未加载对象或者未加载对象的FAssetData 。您可以通过提供一个搜索路径来加载一个对象库,它将加载那个路径中的所有资源。

StreamableManager:是使用同步异步加载功能时直接操作的类

接下来我们要实现一个功能就是将MenuTex文件下的图片资源加载进来,然后在屏幕上切换显示。

效果。

创建ObjectLibrary并加载指定文件夹下资源的弱引用

首先在WelathActor.h中声明定义ObjectLibrary成员变量,然后在WelathActor.cpp中实例ObjectLibrary对象,并指定文件夹。

//声明对象;
UObjectLibrary* ObjectLibrary;
//图片路径软引用;
TArray<FSoftObjectPath> TexturePath;

//实例ObjectLibrary对象,指定文件夹,并将软引用赋值给TexturePath
void AWelathActor::ObjectLibraryOperate()
{
	if (!ObjectLibrary)
	{
		ObjectLibrary = UObjectLibrary::CreateLibrary(UObject::StaticClass(), false, false);
		ObjectLibrary->AddToRoot();
	}

	//搜索所有Texture的路径;
	ObjectLibrary->LoadAssetDataFromPath(TEXT("/Game/Resource/UI/Texture/MenuTex"));

	TArray<FAssetData> TextureData;
	ObjectLibrary->GetAssetDataList(TextureData);

	for (int i=0; i<TextureData.Num();++i)
	{
		//FWHelper::Debug(TextureData[i].ToSoftObjectPath().ToString());
		TexturePath.AddUnique(TextureData[i].ToSoftObjectPath());
	}
}

创建StreamableManager实现异步加载

首先声明一个StreamableManager的对象,调用StreamableManager.RequestAsyncLoad来异步加载资源,这个函数可以传入一个完成加载的回调函数,并且返回一个FStreamableHandle,我们将这个返回值保存,这个值里保存了加载完成的资源数据,所以在.h文件里我们还要声明个FStreamableHandle对象引用。

FStreamableManager* WealthLoader;

TSharedPtr<FStreamableHandle> WealthHandle;


void AWelathActor::StreamableManagerOperate()
{
	WealthLoader = new FStreamableManager();
	WealthHandle = WealthLoader->RequestAsyncLoad(TexturePath, FStreamableDelegate::CreateUObject(this,
		& AWelathActor::StreamableManagerLoadComplete));
}

void AWelathActor::StreamableManagerLoadComplete()
{
	TArray<UObject*> OutObjects;
	WealthHandle->GetLoadedAssets(OutObjects);

	for (int i = 0; i < OutObjects.Num(); i++)
	{
		UTexture2D* workTexture = Cast<UTexture2D>(OutObjects[i]);
		if (workTexture)
		{
			TextureGroup.Add(workTexture);
		}
	}

	FTimerDelegate UpdateTextureDele = FTimerDelegate::CreateUObject(this, &AWelathActor::UpdateTexture);
	GetWorld()->GetTimerManager().SetTimer(UpdateTextureHandle, UpdateTextureDele, 1.f, true);
}

完整代码

WelathActor.h

class UWealthWidget;
struct FStreamableManager;
struct FStreamableHandle;
UCLASS()
class FRAMECOURSE_API AWelathActor : public AActor
{
	GENERATED_BODY()
	
public:	
	// Sets default values for this actor's properties
	AWelathActor();



protected:
	// Called when the game starts or when spawned
	virtual void BeginPlay() override;
    //更新图片;
	void UpdateTexture();
    //资源库对象操作;
	void ObjectLibraryOperate();

    //UMG面板用来展示图片;
	UWealthWidget* WealthWidget;


	//资源异步加载;
	void StreamableManagerOperate();

	//资源异步加载的完成;
	void StreamableManagerLoadComplete();


public:	
	// Called every frame
	virtual void Tick(float DeltaTime) override;
    
    //绑定UMG面板,这个函数是在对应的widget类里调用;
	void AssignWealthWidget(UWealthWidget* wealthWidget);

    //资源库对象指针;
	UObjectLibrary* ObjectLibrary;

    //资源软引用数组;
	TArray<FSoftObjectPath> TexturePath;

    //异步加载管理器;
	FStreamableManager* WealthLoader;
    //图片数组;
	TArray<UTexture2D*> TextureGroup;
	int TextureIndex;
};

WelathActor.ccp

#include "WelathActor.h"
#include "FWCommon.h"
#include "TimerManager.h"
#include "Engine/ObjectLibrary.h"
#include "WealthWidget.h"
#include "Engine/StreamableManager.h"

// Sets default values
AWelathActor::AWelathActor()
{
 	// Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = true;
}

// Called when the game starts or when spawned
void AWelathActor::BeginPlay()
{
	Super::BeginPlay();

	ObjectLibraryOperate();

	StreamableManagerOperate();
}


void AWelathActor::UpdateTexture()
{
	if (TextureGroup.Num() > 0)
	{
		WealthWidget->AssignTexture(TextureGroup[TextureIndex]);
		if (HandleWidget)HandleWidget->AssignTexture(TextureGroup[TextureIndex]);
		TextureIndex = (TextureIndex + 1) >= TextureGroup.Num() ? 0 : (TextureIndex + 1);
	}
}

void AWelathActor::ObjectLibraryOperate()
{
	if (!ObjectLibrary)
	{
		ObjectLibrary = UObjectLibrary::CreateLibrary(UObject::StaticClass(), false, false);
		ObjectLibrary->AddToRoot();
	}

	//搜索所有Texture的路径;
	ObjectLibrary->LoadAssetDataFromPath(TEXT("/Game/Resource/UI/Texture/MenuTex"));

	TArray<FAssetData> TextureData;
	ObjectLibrary->GetAssetDataList(TextureData);

	for (int i=0; i<TextureData.Num();++i)
	{
		//FWHelper::Debug(TextureData[i].ToSoftObjectPath().ToString());
		TexturePath.AddUnique(TextureData[i].ToSoftObjectPath());
	}
}

void AWelathActor::StreamableManagerOperate()
{
	WealthLoader = new FStreamableManager();
	WealthHandle = WealthLoader->RequestAsyncLoad(TexturePath, FStreamableDelegate::CreateUObject(this,
		& AWelathActor::StreamableManagerLoadComplete));
}

void AWelathActor::StreamableManagerLoadComplete()
{
	TArray<UObject*> OutObjects;
	WealthHandle->GetLoadedAssets(OutObjects);

	for (int i = 0; i < OutObjects.Num(); i++)
	{
		UTexture2D* workTexture = Cast<UTexture2D>(OutObjects[i]);
		if (workTexture)
		{
			TextureGroup.Add(workTexture);
		}
	}
    //定时更新;
	FTimerDelegate UpdateTextureDele = FTimerDelegate::CreateUObject(this, &AWelathActor::UpdateTexture);
	GetWorld()->GetTimerManager().SetTimer(UpdateTextureHandle, UpdateTextureDele, 1.f, true);
}


// Called every frame
void AWelathActor::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);

}

void AWelathActor::AssignWealthWidget(UWealthWidget* wealthWidget)
{
	WealthWidget = wealthWidget;

}

这里我省略了创建WelathActor蓝图和WeathWidget的步骤,具体完整的流程可以到迪迪教程第二期资源加载视频中去看。

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值