UE4 异步资源加载

本文介绍了虚幻引擎4中异步资源加载的几种方法,包括FStringAssetReferences和TAssetPtr的使用,资源注册表和对象库的概念,以及StreamableManager在动态加载中的作用。通过这些技术,可以优化游戏性能,减少主线程停顿,提高资源管理效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow

也欢迎大家转载本篇文章。分享知识,造福人民,实现我们中华民族伟大复兴!

               

概述

虚幻引擎4中有几个新系统,使得可以更加轻松地异步加载资源数据,这些系统代替了虚幻引擎3中的免搜索内容包中存在的很多功能。这些新方法既可以在开发数据应用也可以在设备上的烘焙数据上进行应用,所以您不必保留两个根据需要加载数据的代码路径。有两种通用的方法可以供您根据需要来引用及加载数据。

FStringAssetReferences 和TAssetPtr

美术师或设计师引用资源的最简单的方法是,创建一个UProperty 强指针,并赋予其一个类目。在虚幻引擎4中,如果您使用强指针UObject 属性引用一个资源,那么当加载包含该属性的对象时将会加载那个资源(通过把对象放置在地图中,或者通过从类似于游戏信息这样的东西中进行引用该对象)。如果您不关心是否在游戏启动时能够100%地加载您的资源。如果您想让 美术师/设计师 使用和强指针一样的用户界面来引用特定的资源,而不是总是加载引用的资源,请使用 FStringAssetReference 或 TAssetPtr 。

FStringAssetReference 是一个简单的结构体,包含了一个具有资源完整名称的字符串。如果您在类中创建一个那种类型的属性,那么它将会显示在编辑器中,就像是个 UObject * 属性一样。它还可以正确地处理烘焙和重定向,所以如果您有一个StringAssetReference,那么它一定可以在设备上正常工作。TAssetPtr基本上就是一个封装了 FStringAssetReference 的 TWeakObjectPtr ,它使用一个特定的类作为模板,以便您能限制编辑器用户界面,使其仅允许选择特定的类。如果所引用的资源存在于内存中,那么 TAssetPtr.Get() 将返回该资源。如果该资源不在内存中,那么您那可以调用 ToStringReference() 来查找它引用的资源,并使用下面介绍的方法加载该资源,然后再次调用TAssetPtr.Get() 解除对该资源的引用。

如果美术师或设计师正在手动地设置引用,那么使用 TAssetPtrs 和 StringAssetReferences是非常适合的,但如果您想进行类似于查询这样的处理,查找满足特定要求的资源,而不是加载所有资源,那么您应该使用资源注册表及对象库。

资源注册表和对象库

资源注册表是一个存储资源的元数据的系统,允许您搜索及查询这些资源。编辑器使用此资源注册表来显示内容浏览器中的信息,但是您也可以从游戏性代码使用该注册表,来查找当前没有加载的游戏资源的相关元数据。要想使得一个资源的数据是可搜索的,您需要给该属性添加"AssetRegistrySearchable"标签。查询资源注册表会返回FAssetData类型的对象,它包含了关于该对象的信息和一个 键-》值 对映射表,该映射表包含了标记为可搜索的属性。

处理成组的未加载的资源的最简单方法是使用 ObjectLibrary 。ObjectLibrary 是一个对象&#x

<think>嗯,用户问的是在Unreal Engine中如何实现异步加载。我需要先回想一下UE异步加载的常用方法。首先,可能想到的是使用AsyncLoad资产,比如UAssetManager或者FStreamableManager。然后,还有异步加载关卡的功能,比如使用LoadStreamLevel或者Level Streaming的蓝图节点。另外,可能还要提到异步加载纹理、静态网格等资源的具体方法,比如使用FStreamableHandle或者AsyncTask。 不过用户可能是一个刚开始学习UE的开发者,可能对异步加载的概念不太清楚,需要先解释一下为什么需要异步加载,比如避免主线程卡顿,提升用户体验。然后分步骤介绍不同的方法,比如资源加载和关卡加载的区别。可能需要提到使用PrimaryAssetId来标识资源,然后通过AsyncLoadPrimaryAsset来加载。另外,FStreamableManager的RequestAsyncLoad也是一个常用的方法,可以加载一组资源并在完成后回调。 在代码示例方面,用户可能需要看到具体的C++或者蓝图的例子。比如在C++中,如何声明FStreamableManager,如何绑定回调函数。在蓝图中,可能使用Delay节点或者Async Load Asset节点,但要注意蓝图的异步操作可能需要使用到事件分发器或者Latent Action。 还要注意资源管理的问题,比如加载后的资源需要正确释放,避免内存泄漏。可能需要提醒用户在使用完毕后手动Unload,或者使用引用计数。另外,异步加载过程中的错误处理也很重要,比如加载失败的情况需要处理,可以添加OnLoadFailed的回调。 可能用户的实际应用场景是在游戏运行时动态加载角色模型、场景元素或者大型地图,所以举例说明这些情况会更有帮助。比如在开放世界游戏中,当玩家接近某个区域时,异步加载该区域的关卡和资源,以保证流畅性。 需要确认UE的版本是否影响异步加载的实现方式,比如在UE4UE5中是否有差异。不过一般来说,FStreamableManager和AsyncLoadPrimaryAsset在两者中都是可用的。此外,还可以提到Unreal的异步加载系统底层可能使用了Pak文件加载,或者基于AsyncLoadingThread的机制,但用户可能不需要了解这么深入,除非有特别需求。 总结起来,回答的结构应该是先介绍异步加载的作用,然后分资源加载和关卡加载两部分,分别介绍实现方法,给出C++和蓝图的示例,最后提一下注意事项和最佳实践。这样用户能够有一个清晰的步骤去实现,同时了解潜在的问题和解决方案。</think>在虚幻引擎(Unreal Engine)中,异步加载的核心目标是避免主线程阻塞,提升运行效率。以下是分步实现方法: --- ### **一、异步加载资源(纹理、模型等)** #### **1. 使用 `FStreamableManager`** ```cpp // 头文件声明 #include "UObject/SoftObjectPath.h" #include "Engine/StreamableManager.h" // 代码实现 void UMyClass::LoadAssetAsync() { FStreamableManager& Streamable = UAssetManager::GetStreamableManager(); TArray<FSoftObjectPath> AssetsToLoad; AssetsToLoad.Add(FSoftObjectPath(TEXT("/Game/Textures/MyTexture.MyTexture"))); // 异步加载并绑定回调 Streamable.RequestAsyncLoad(AssetsToLoad, FStreamableDelegate::CreateUObject(this, &UMyClass::OnAssetsLoaded)); } void UMyClass::OnAssetsLoaded() { // 资源加载完成后的逻辑 UTexture2D* LoadedTexture = LoadObject<UTexture2D>(nullptr, TEXT("/Game/Textures/MyTexture.MyTexture")); } ``` #### **2. 蓝图实现** 1. 使用 **`Async Load Asset`** 节点 2. 连接 **`OnLoadCompleted`** 事件处理加载结果 --- ### **二、异步加载关卡** #### **1. C++ 实现** ```cpp void UMyClass::LoadLevelAsync() { FLatentActionInfo LatentInfo; LatentInfo.CallbackTarget = this; LatentInfo.ExecutionFunction = "OnLevelLoaded"; LatentInfo.Linkage = 0; UGameplayStatics::LoadStreamLevelBySoftObjectPtr(GetWorld(), LevelToLoad, true, true, LatentInfo); } void UMyClass::OnLevelLoaded() { // 关卡加载完成后的逻辑 } ``` #### **2. 蓝图实现** 1. 使用 **`Load Stream Level`** 节点 2. 勾选 **`Make Visible After Load`** 和 **`Should Block on Load`** 参数 --- ### **三、异步加载数据资产** ```cpp // 使用 Primary Asset 系统 void UMyClass::LoadPrimaryAssetAsync() { TArray<FPrimaryAssetId> AssetsToLoad; AssetsToLoad.Add(FPrimaryAssetId("MyAssetType", "MyAssetName")); UAssetManager::Get().LoadPrimaryAssets(AssetsToLoad, TArray<FName>(), FStreamableDelegate::CreateUObject(this, &UMyClass::OnPrimaryAssetLoaded)); } ``` --- ### **四、关键技术点** 1. **回调机制**:通过 `FStreamableDelegate` 或蓝图事件绑定后续逻辑 2. **资源引用**:保持对加载资源的强引用(如 `UPROPERTY()`),防止被GC回收 3. **进度跟踪**:通过 `GetAsyncLoadPercentage()` 监控加载进度 4. **错误处理**:检查加载结果有效性,处理加载失败情况 --- ### **五、最佳实践** - 对大型资源(如4K纹理)使用异步加载 - 在场景过渡时预加载下一场景资源 - 结合加载屏幕(Loading Screen)显示进度条 - 使用 `CancelLoading()` 支持取消操作 --- 通过结合C++底层控制和蓝图可视化编程,可以灵活实现不同复杂度的异步加载需求。实际开发中需根据性能分析和项目需求选择最合适的方案。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值