【虚幻引擎】UE4 同步和异步资源加载(软引用)

这篇具有很好参考价值的文章主要介绍了【虚幻引擎】UE4 同步和异步资源加载(软引用)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

B站教学链接:https://space.bilibili.com/449549424?spm_id_from=333.1007.0.0 一、引用介绍

虚幻引擎给我们提供了两种引用,一个是硬引用。软引用通常是仅储存资源对象的资源路径没有与资源产生耦合关系的引用(软引用加载到内存中,引用对象不会被加载到内存中,只有在需要的时候才会被加载进内存中)。硬引用则是拥有资源对象实际成员变量,直接与资源对象产生耦合(硬引用被加载到内存中,则被引用的对象资源也会被加载到内存中)。

在UE4开发中经常性需要获取一些资源(StaticMesh,Material,Particle,Datatable, Actor蓝图,各种继承UObject的蓝图等等)的路径,然后利用这些路径进行资源的加载。

蓝图类资源,也就是BlueprintClass,继承于UObject并且蓝图化的资源。

【虚幻引擎】UE4 同步和异步资源加载(软引用) 非蓝图类资源:UTexture,UStaticMesh,UParticleSystem,UMaterialInterface这些资源:如纹理,粒子,静态网格,材质等等。

【虚幻引擎】UE4 同步和异步资源加载(软引用)

 二、软引用

在UE4中,我们常用的软引用有以下四种 FSoftObjectPath、FSoftClassPath、FSoftObjectPtr、TSubclassOf 这四个。

FSoftObjectPath:翻译成“软对象路径”,也就是在一个(UObject,UStruct,Actor,ActorCompoennt)对象中配置一个具体资源(非蓝图资源和蓝图资源都可以)的路径,当这个对象被加载的时候,FSoftObjectPath指向的资源未被加载,仅仅是提供了一个路径。

蓝图中的应用:


	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Ftr")
		FSoftObjectPath AssetObjectPath;

【虚幻引擎】UE4 同步和异步资源加载(软引用)

如果我们需要某些特定的资源路径,可以使用元数据,meta = (AllowedClasses ="Material,StaticMesh"),他就只会选择你设置的类型 ,

注意1:FSoftObjectPath用AllowedClasses 只能筛选"Material,StaticMesh,Particle等资源

注意2:Material,StaticMesh类型之间不能有空格

【虚幻引擎】UE4 同步和异步资源加载(软引用)

 FSoftClassPath:对蓝图资源的一种弱引用,类似FSoftObjectPath,继承自FSoftObjectPath,可以说是FSoftObjectPath的进一步封装,不过这里是蓝图资源,指向了蓝图资源的路径,通过路径我们可以手动加载。

UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Ftr")
		FSoftClassPath AssetClassPath;

【虚幻引擎】UE4 同步和异步资源加载(软引用)

本质是FSoftClassPath指向的资源的路径为FSoftObjectPath的指向资源路径的子集 

TSoftObjectPtr:软对象指针用于在异步加载并且资源加载完成触发回调函数的时候获取资源对应的对象指针用的,毕竟异步加载是无法直接获取对象指针的。

//软引用获得资源对象的指针,仅储存资源对象的资源路径没有与资源产生耦合关系的引用
   //(软引用加载到内存中,引用对象不会被加载到内存中,只有在需要的时候才会被加载进内存中)
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Ptr")
		TSoftObjectPtr<AActor> softActorobj;

【虚幻引擎】UE4 同步和异步资源加载(软引用)

 TSoftClassPtr:检测蓝图资源加载,获取蓝图资源对应的指针

UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Ptr")
		TSoftClassPtr<AActor> softActorClass;

同样的可以直接用TSoftObjectPtr来获取UClass的指针,因为UClass本身就是UObject的子类。

三、同步加载

在UE4中使用同步加载RequestSyncLoad和异步加载RequestASyncLoad,就要提到一个类FStreamableManager,用于管理流资产并将其保存在内存中的本机类。

第一种同步加载的方式RequestSyncLoad

源码分析:

TSharedPtr<FStreamableHandle> FStreamableManager::RequestSyncLoad(const FSoftObjectPath& TargetToStream, bool bManageActiveHandle, FString DebugName)
{
	return RequestSyncLoad(TArray<FSoftObjectPath>{TargetToStream}, bManageActiveHandle, MoveTemp(DebugName));
}

参数解释:

  • TargetsToStream要加载的资产磁盘。
  • bManageActiveHandle如果为true,管理器将保持流句柄活动,直到显式释放。
  • DebugName此句柄的名称,将在调试工具中报告。

测试案例介绍:

FSoftObjectPath Path2 = FString(TEXT("Texture2D'/Game/StarterContent/Textures/T_Brick_Clay_Beveled_M.T_Brick_Clay_Beveled_M'"));
	//注意:在资源未完成加载之前代码会在这一行暂停运行以等待资源加载完成。
	TSharedPtr<FStreamableHandle> SyncStreamableHandle2 = UAssetManager::GetStreamableManager().RequestSyncLoad(Path2);
	if (SyncStreamableHandle2)
	{
		//使用RequestSyncLoad(方法加载单个资源的时候要用GetLoadedAsset来获得FStreamableHandle中返回的资源。
		UTexture2D* Image2 = Cast<UTexture2D>(SyncStreamableHandle2->GetLoadedAsset());
		if (Image2)
		{
			UE_LOG(LogTemp, Warning, TEXT("Image2 is %s"), *Image2->GetName());
		}
	}

注意:资源的引用在Content Browser中右键该资产,再选择Copye Reference即可复制路径

结果:

【虚幻引擎】UE4 同步和异步资源加载(软引用)

同步加载资源组:

源码分析:

/** 
	 * Synchronously load a set of assets, and return a handle. This can be very slow and may stall the game thread for several seconds.
	 * 
	 * @param TargetsToStream		Assets to load off disk
	 * @param bManageActiveHandle	If true, the manager will keep the streamable handle active until explicitly released
	 * @param DebugName				Name of this handle, will be reported in debug tools
	 */
TSharedPtr<FStreamableHandle> RequestSyncLoad(TArray<FSoftObjectPath> TargetsToStream, bool bManageActiveHandle = false, FString DebugName = TEXT("RequestSyncLoad Array"));

参数解释:

  • TargetsToStream要加载的资产磁盘。
  • bManageActiveHandle如果为true,管理器将保持流句柄活动,直到显式释放。
  • DebugName此句柄的名称,将在调试工具中报告。

案例测试: 

//同步加载资源组
	TArray<FSoftObjectPath> Paths;
	Paths.AddUnique(FString(TEXT("Texture2D'/Game/StarterContent/Textures/T_Brick_Clay_Beveled_N.T_Brick_Clay_Beveled_N'")));
	Paths.AddUnique(FString(TEXT("Texture2D'/Game/StarterContent/Textures/T_Brick_Clay_New_D.T_Brick_Clay_New_D'")));
	//注意:在资源未完成加载之前代码会在这一行暂停运行以等待资源加载完成。
	TSharedPtr<FStreamableHandle> SyncStreamableHandle3 = UAssetManager::GetStreamableManager().RequestSyncLoad(Paths);
	if (SyncStreamableHandle3)
	{
		TArray<UObject*>LoadedAssets;
		SyncStreamableHandle3->GetLoadedAssets(LoadedAssets);
		if (LoadedAssets.Num() > 0)
		{
			for (int32 i = 0; i < LoadedAssets.Num(); i++)
			{
				UTexture2D* Image3 = Cast<UTexture2D>(LoadedAssets[i]);
				if (Image3)
				{
					UE_LOG(LogTemp, Warning, TEXT("Image3 is %s"), *Image3->GetName());
				}
			}
		}
	}

注意,使用这个方法加载单个资源的时候要用GetLoadedAsset来获得FStreamableHandle中返回的资源。 

结果:

【虚幻引擎】UE4 同步和异步资源加载(软引用)

同步加载单个资源LoadSynchronous ,实际上是对RequestSyncLoad的一层封装

源码分析:

UObject* LoadSynchronous(const FSoftObjectPath& Target, bool bManageActiveHandle = false, TSharedPtr<FStreamableHandle>* RequestHandlePointer = nullptr);

	/** Typed wrappers */
	template< typename T >
	T* LoadSynchronous(const FSoftObjectPath& Target, bool bManageActiveHandle = false, TSharedPtr<FStreamableHandle>* RequestHandlePointer = nullptr)
	{
		return Cast<T>(LoadSynchronous(Target, bManageActiveHandle, RequestHandlePointer) );
	}

	template< typename T >
	T* LoadSynchronous(const TSoftObjectPtr<T>& Target, bool bManageActiveHandle = false, TSharedPtr<FStreamableHandle>* RequestHandlePointer = nullptr)
	{
		return Cast<T>(LoadSynchronous(Target.ToSoftObjectPath(), bManageActiveHandle, RequestHandlePointer));
	}

案例测试:

//同步加载单个资源LoadSynchronous
	FSoftObjectPath Path =FString(TEXT("Texture2D'/Game/StarterContent/Textures/T_Brick_Clay_Beveled_D.T_Brick_Clay_Beveled_D'"));
	UTexture2D* Image = UAssetManager::GetStreamableManager().LoadSynchronous<UTexture2D>(Path,false,nullptr);
	if (Image)
	{
		UE_LOG(LogTemp,Warning,TEXT("Image is %s"),*Image->GetName());
	}

结果:

【虚幻引擎】UE4 同步和异步资源加载(软引用)

注意:该方法或许适用于较小对象,但可能会导致主线程长时间停滞。在这种情况下,您将需要使用RequestAsyncLoad,它将异步加载一组资源并在完成后调用委托。 

四、异步加载 

UE4异步加载RequestAsyncLoad

源码分析:

/** 
	 * This is the primary streamable operation. Requests streaming of one or more target objects. When complete, a delegate function is called. Returns a Streamable Handle.
	 *
	 * @param TargetsToStream		Assets to load off disk
	 * @param DelegateToCall		Delegate to call when load finishes. Will be called on the next tick if asset is already loaded, or many seconds later
	 * @param Priority				Priority to pass to the streaming system, higher priority will be loaded first
	 * @param bManageActiveHandle	If true, the manager will keep the streamable handle active until explicitly released
	 * @param bStartStalled			If true, the handle will start in a stalled state and will not attempt to actually async load until StartStalledHandle is called on it
	 * @param DebugName				Name of this handle, will be reported in debug tools
	 */
	TSharedPtr<FStreamableHandle> RequestAsyncLoad(TArray<FSoftObjectPath> TargetsToStream, FStreamableDelegate DelegateToCall = FStreamableDelegate(), TAsyncLoadPriority Priority = DefaultAsyncLoadPriority, bool bManageActiveHandle = false, bool bStartStalled = false, FString DebugName = TEXT("RequestAsyncLoad ArrayDelegate"));
	TSharedPtr<FStreamableHandle> RequestAsyncLoad(const FSoftObjectPath& TargetToStream, FStreamableDelegate DelegateToCall = FStreamableDelegate(), TAsyncLoadPriority Priority = DefaultAsyncLoadPriority, bool bManageActiveHandle = false, bool bStartStalled = false, FString DebugName = TEXT("RequestAsyncLoad SingleDelegate"));

参数解释:

  • TargetsToStream要加载的资产磁盘。

DelegateToCall委托在加载完成时调用。将被调用在下一个Tick,如果资产已加载,或许多秒后。

  • Priority优先级传递给流系统,优先级高的将首先加载。
  • bManageActiveHandle如果为true,管理器将保持流句柄活动,直到显式释放。
  • bStartStalled如果为true,句柄将以停滞状态启动,并且在调用StartStalledHandle之前不会尝试实际异步加载。
  • DebugName此句柄的名称,将在调试工具中报告。

案例测试

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Test")
		TArray<TSoftObjectPtr<UTexture2D>> ObjectPtrs;

	TSharedPtr<FStreamableHandle> ASyncStreamableHandle2;
	void AsyncLoadCompleted();

蓝图资源配置

【虚幻引擎】UE4 同步和异步资源加载(软引用)

//异步加载单个资源
	FSoftObjectPath Path4 = TEXT("Texture2D'/Game/StarterContent/Textures/T_Ceramic_Tile_M.T_Ceramic_Tile_M'");
	TSharedPtr<FStreamableHandle> ASyncStreamableHandle = UAssetManager::GetStreamableManager().RequestAsyncLoad(Path4);
	if (ASyncStreamableHandle)
	{
		UTexture2D* Image4 = Cast<UTexture2D>(ASyncStreamableHandle->GetLoadedAsset());
		if (Image4)
		{
			UE_LOG(LogTemp, Warning, TEXT("Image4 is %s"), *Image4->GetName());
		}
	}
	//异步加载资源组
	TArray<FSoftObjectPath>Paths2;
	for (auto item:ObjectPtrs)
	{
		Paths2.AddUnique(item.ToSoftObjectPath());//ToSoftObjectPath()返回的是一个智能指针
	}
	ASyncStreamableHandle2 = UAssetManager::GetStreamableManager().RequestAsyncLoad(Paths2, FStreamableDelegate::CreateUObject(this, &AMyActor::AsyncLoadCompleted));
}



void AMyActor::AsyncLoadCompleted()
{
	if (ASyncStreamableHandle2)
	{
		TArray<UObject*>ObjectArray;
		ASyncStreamableHandle2->GetLoadedAssets(ObjectArray);
		if (ObjectArray.Num()>0)
		{
			for (int i = 0; i < ObjectArray.Num(); i++)
			{
				UTexture2D* Image5 = Cast<UTexture2D>(ObjectArray[i]);
				UE_LOG(LogTemp, Warning, TEXT("Image5 is %s"), *Image5->GetName());
			}
		}
	}
}

结果:

异步加载单个资源

【虚幻引擎】UE4 同步和异步资源加载(软引用)

异步加载资源组

【虚幻引擎】UE4 同步和异步资源加载(软引用)文章来源地址https://www.toymoban.com/news/detail-429808.html

到了这里,关于【虚幻引擎】UE4 同步和异步资源加载(软引用)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【虚幻引擎】UE4/UE5 pak挂载

     找到:D:UEUE_4.27EngineBinariesWin64,  WindowS+R打开CMD命令 运行UnrealPak,运行结果如下      注意如果想要加载Pak内资源,那么这些资源必须是经过Cook的。如果打包的是未Cook的资源,那么即使Pak挂载成功,也不可能会成功加载Pak内资源。  Cook好之后,存储的路径在你的I:DBJ

    2024年02月10日
    浏览(75)
  • 【虚幻引擎】UE4 Spline(样条线)

           样条线Spline在UE中是一个很好用的工具,能够设置物体的跟随移动,也能够设置物体的批量复制,还能够设置一个特殊的模型形状比如圆管,还可以设置特殊的粒子特效,做地形设计等等,只要你想要实现的效果,spline都可以实现。官方也提供了很多的案例,可以参考

    2023年04月10日
    浏览(67)
  • 【虚幻引擎UE】UE4/UE5 新人科普向

    Unreal Engine是当前最为流行的游戏引擎之一,具有丰富的游戏开发功能和强大的游戏引擎渲染能力。 UE5官方文档:UE5官方文档非常详细,介绍了UE5的各个功能和应用,适合入门学习和深入探究。链接:https://docs.unrealengine.com/5.1/zh-CN/ UE5中文社区:该社区聚集了大量的UE5开发者,

    2024年02月09日
    浏览(79)
  • 【虚幻引擎】UE4 FTabmanager实现多窗口

    我们先看源码的实现方式:FTabmanager类实现了创建窗口的不同方法 NewLayout:创建新的布局方式  RegisterTabSpawner:注册在模块启动时的函数,这个就是创建了一个窗口,窗口所放置的内容  RestoreFrom:从窗口中显示 调用独立窗口需要在模块启动的时候调用FGlobalTabmanager::Get()的Re

    2024年02月10日
    浏览(76)
  • 【虚幻引擎】UE4/UE5科大讯飞文字合成语音

    B站视频链接:https://space.bilibili.com/449549424?spm_id_from=333.1007.0.0   第一步:首先进入讯飞开放平台注册一个账号,然后创建一个 创建一个应用,命名按照你自己的想法来,会产生一个APPID,具体参考UE4如何接入科大讯飞的语音识别_ue4 科大讯飞的语音识别_飞起的猪的博客-CSDN博

    2024年02月13日
    浏览(72)
  • 【虚幻引擎】UE4/UE5鼠标点击事件实现物体移动

     在UE4/UE5中,引擎有它自己的一套框架体系,虚幻就是基于这一个框架体系来实现的。其中就有PlayerController(玩家控制器),玩家控制器中就有对鼠标的一系列设置,包括显示鼠标,允许点击事件等。  1.创建PlayerController,命名为MyPlayerController 2.打开MyPlayerController,勾选参数

    2024年02月10日
    浏览(115)
  • 【虚幻引擎】UE4/UE5数字孪生与前端Web页面匹配

            数字孪生是一种多维动态的数字映射,可大幅提高效能。数字孪生是充分利用物理模型、传感器更新、运行历史等数据,集成多学科、多物理量、多尺度、多概率的仿真过程,在虚拟空间中完成对现实体的复制和映射,从而反映物理实体的全生命周期过程。数字孪生

    2024年02月03日
    浏览(80)
  • 虚幻引擎4崩溃?10个UE4崩溃解决方法来了

    虚幻引擎 4 在PC上运行出现不断崩溃的情况?你绝对不是一个人,成千上万的用户最近报告了同样的问题。但好消息是你可以修复它。以下是已证明对许多玩家有用的解决方案列表。 如何修复虚幻引擎4的崩溃问题,下面这10个解决办法一起来看看吧。 虚幻引擎 的开发者不断

    2024年02月04日
    浏览(55)
  • 【虚幻引擎】UE4 动画蓝图,动画,状态机三者之间的联系

    动画蓝图是将基础动作整到一起并且能够使得动作之间切换变得很自然的一个蓝图。 以第三人称为例  动画:每一个基础动作都是一个动画资源,基础动作包括,站立,行走,跑步,蹲下,跳跃等  创建一个动画蓝图,需要有一套骨架才可以,对于一个有动画的人物,必须要

    2024年02月09日
    浏览(63)
  • 【虚幻引擎】UE4 Windows下打包Linux版本的包

    首先上官网下载对应版本的工具链安装 官网链接;:https://docs.unrealengine.com/4.26/en-US/SharingAndReleasing/Linux/GettingStarted/ 下载完之后点击安装exe,等待安装完成  二、检查是否安装成功 在cmd中运行 %LINUX_MULTIARCH_ROOT%x86_64-unknown-linux-gnubinclang++ -v , 出现这个提示表示运行成功  三、在

    2024年02月14日
    浏览(46)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包