【UE4】资源管理之UAssetManager用法
UAssetManager用法
文章目录
- UAssetManager用法
- 一、PrimaryAsset和SecondaryAsset
- 二、PrimaryAssetId和PrimaryAssetType
- 三、将PrimaryAsset进行注册
- 四、AssetManager
- 五、资源加载
- 六、资源束
- 其它文档
UAssetManager通过名字就可以了解,这个类是对资源进行管理。一般情况下,UE4会自动加载与卸载资源,但是如果开发者(就是我们)想更精确地掌控资源发现、加载与审核的时机与方法,那这个UAssetManager就可以上场帮忙了。下面,我们一步一步解析,这个UAssetManager如何使用。
一、PrimaryAsset和SecondaryAsset
首先,我们来对资源进行分类。我们把资源分为PrimaryAsset(主资源)和SecondaryAsset(次资源)两类。
那什么是PrimaryAsset和SecondaryAsset资源呢?下边是网上其他博主给的,大家自行参考。原文链接
Primary Assets指的是在游戏中可以进行手动载入/释放的东西。包括地图文件以及一些游戏相关的物件,例如character classs或者inventory items.
Secondary Assets指的是其他的那些Assets了,例如贴图和声音等。这一类型的assets是根据Primary Assets来自动进行载入的。
而AssetManager就是来直接管理这个PrimaryAsset,SecondaryAsset则会在主资源加载后自动载入。
但默认情况下,只有关卡(Map)(/Game/Maps)是PrimaryAsset(可能后边会发现还有一个PrimaryAssetLabel,这个暂时忽略)。
那如何将SecondaryAsset设为PrimaryAsset呢?那第一步就是给资源类实现 virtual FPrimaryAssetId GetPrimaryAssetId() const override; 接口方法。
下边是方法的实现:
//GetPrimaryAssetId是在UObject就声明的抽象函数,所以不用担心父类没有这个抽象方法。
FPrimaryAssetId XXX::GetPrimaryAssetId() const
{//AssetType是FPrimaryAssetType类型的变量,应该如何定义,我们在下节说明return FPrimaryAssetId(AssetType, GetFName());
}
AssetManager通过FPrimaryAssetId来对指定的资源对象进行管理,而上述成员方法就是来获取这个AssetID的,所以说只有实现这个方法,才能对该类型资源进行管理。
AssetType和AssetId是什么关系?定义上述方法就OK了吗?其实,还真没那么简单,下面进行更详细的说明解释。
小结:UAssetManager可以直接管理PrimaryAsset。将类实现GetPrimaryAssetId方法是成为PrimaryAsset的第一步。
二、PrimaryAssetId和PrimaryAssetType
我们通过上一节了解到,如果要将资源提升为PrimaryAsset,需要实现GetPrimaryAssetId方法。方法的返回值就是AssetManager对这个资源进行管理的标识符了。
返回FPrimaryAssetId对象时,需要传入AssetType和GetFName两个参数。
其中AssetType是FPrimaryAssetType的对象,而GetFName()方法返回的是资源对象名。这两个参数一起确定了这个资源的Id。
我们可以在UAssetManager类中定义FPrimaryAssetType类型的静态变量来定义资源类型。
static const FPrimaryAssetType WeaponType = TEXT("Weapon");
也就是说,我们的资源对象可以属于不同或相同的资源类型,按照资源类型对可以对PriamryAsset进行分类。这里可能解释关于繁琐,并且不好理解,下边会有个代码示例。
三、将PrimaryAsset进行注册
我们通过在C++中通过实现类的GetPrimaryAssetId方法对类进行了Id和Type的设置。如果我们想要在蓝图中对资源进行引用的话,还需要在项目设置里面对AssetType进行注册。换句话说,我们在C++中只是对AssetType进行声明和定义(因为这个AssetType的定义位置比较随意,虽然我们推荐定义在AssetManager,但实际任何位置,甚至直接返回TEXT都可以。),如果要让UE4去识别我们的AssetType,就需要对其进行注册。
首先打开ProjectSettings,然后找到AssetManager,在设置面板里面可以看到PrimaryAssetTypestoScan,这个变量就是对AssetType进行注册的地方了。参数说明请参考官方文档。
这里需要注意的是数组元素里有一项是PrimaryAssetType,这项的值必须与注册的资源返回的Id参数AssetType的TEXT值一致。可能有点绕口,就是说PrimaryAssetType的值与此项注册的资源类在C++中赋值的AssetType一致。
当然,还有一种注册方法,那就是直接在代码中注册。
如希望直接在代码中注册主资源,则覆盖资源管理器类中的 StartInitialLoading 函数并从该处调用 ScanPathsForPrimaryAssets。因此,推荐您将所有同类型的主资源放入相同的子文件夹中。这将使资源查找和注册更为迅速。
ScanPathsForPrimaryAssets(TEXT("Actor"), TArray<FString>{"/Game/Path"}, UObject::StaticClass(), true);
ScanPathForPrimaryAsset(WeaponType, TArray<FString>{"/Game/Path/Items"}, USGItems::StaticClass(), false);
如果使用热编译后,编辑器没有反应,记得重启编辑器试试!!
四、AssetManager
一般情况下,我们不需要创建自己的AssetManager。但如果有一些特殊的需要,比如上例中覆盖StartInitialLoading从而注册资源的话,就需要创建自己的AssetManager了,创建的AssetManager需要继承UAssetManager。下例为ActionRPG中AssetManager的示例:
UCLASS()
class ACTIONRPG_API URPGAssetManager : public UAssetManager
{GENERATED_BODY()public:// Constructor and overridesURPGAssetManager() {}virtual void StartInitialLoading() override;/** Static types for items */static const FPrimaryAssetType PotionItemType;static const FPrimaryAssetType SkillItemType;static const FPrimaryAssetType TokenItemType;static const FPrimaryAssetType WeaponItemType;/** Returns the current AssetManager object */static URPGAssetManager& Get();/*** Synchronously loads an RPGItem subclass, this can hitch but is useful when you cannot wait for an async load* This does not maintain a reference to the item so it will garbage collect if not loaded some other way*/URPGItem* ForceLoadItem(const FPrimaryAssetId& PrimaryAssetId, bool bLogWarning = true);
};
const FPrimaryAssetType URPGAssetManager::PotionItemType = TEXT("Potion");
const FPrimaryAssetType URPGAssetManager::SkillItemType = TEXT("Skill");
const FPrimaryAssetType URPGAssetManager::TokenItemType = TEXT("Token");
const FPrimaryAssetType URPGAssetManager::WeaponItemType = TEXT("Weapon");URPGAssetManager& URPGAssetManager::Get()
{URPGAssetManager* This = Cast<URPGAssetManager>(GEngine->AssetManager);if (This){return *This;}else{UE_LOG(LogActionRPG, Fatal, TEXT("Invalid AssetManager in DefaultEngine.ini, must be RPGAssetManager!"));return *NewObject<URPGAssetManager>(); // never calls this}
}void URPGAssetManager::StartInitialLoading()
{Super::StartInitialLoading();//ScanPathsForPrimaryAssets(TEXT("Actor"), TArray<FString>{"/Game/Path"}, UObject::StaticClass(), true);UAbilitySystemGlobals::Get().InitGlobalData();
}URPGItem* URPGAssetManager::ForceLoadItem(const FPrimaryAssetId& PrimaryAssetId, bool bLogWarning)
{ FSoftObjectPath ItemPath = GetPrimaryAssetPath(PrimaryAssetId);// This does a synchronous load and may hitchURPGItem* LoadedItem = Cast<URPGItem>(ItemPath.TryLoad());if (bLogWarning && LoadedItem == nullptr){UE_LOG(LogActionRPG, Warning, TEXT("Failed to load item for identifier %s!"), *PrimaryAssetId.ToString());}return LoadedItem;
}
并且,我们需要修改配置文件,将AssetManager设置为此类。
五、资源加载
资源管理器函数 LoadPrimaryAssets、LoadPrimaryAsset 和 LoadPrimaryAssetsWithType 可用于在适当的时间开始加载主资源。之后资源可通过 UnloadPrimaryAssets、UnloadPrimaryAsset 和 UnloadPrimaryAssetsWithType 进行卸载。使用这些加载函数时,可指定一个资源束列表。以此法进行加载将使资源管理器按以上描述的方式加载这些资源束应用的次资源。
蓝图中也提供了许多资源管理的静态方法,例如GetPrimaryAssetIdList方法可以通过传入资源类型,返回此类型所有资源对象的ID,然后通过AsyncLoadPrimaryAssetList就可以批量异步加载此类型的资源对象。其它方法的使用自行测试。
六、资源束
资源束的内容后期补充,这里先参考官方文档。
资源束(Asset Bundle) 是与主资源相关特定资源的命名列表。用“AssetBundles”元标签对 UObject 的 TAssetPtr 或 FStringAssetReference 成员的 UPROPERTY 代码段进行标记即可创建资源束。标签的数值将显示保存次资源的束的命名。举例而言,以下保存在 MeshPtr 成员变量中的静态网格体资源在 UObject 被保存时将被添加到名为“TestBundle”的资源束。
/** 模型 */
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = Display, AssetRegistrySearchable, meta = (AssetBundles = "TestBundle"))
TAssetPtr<UStaticMesh> MeshPtr;
其它文档
《官方文档-资源管理》
【UE4】资源管理之UAssetManager用法相关推荐
- 虚幻引擎编辑器开发基础(一)
虚幻引擎编辑器开发基础(一) 文章目录 虚幻引擎编辑器开发基础(一) 一.前言 二.插件与模块 2.1 插件(Plguin) 2.1.1 插件的作用 2.1.2 插件的类型 2.1.3 插件结构 2. ...
- UE4 AssetManager
UE4 AssetManager 介绍 UAssetManager是UE4提供给开发者的资源管理类,大家知道一般情况下UE4会自动加载和卸载资源,然而我们有些时候项目需要对资源有更多地掌控则就需要它来 ...
- UE4 资源加载与资源缓存
前一段时间其实就做完了这个资源预加载的功能,仅仅是根据以往的经验完成的这项功能.最近稍微有一点时间,就把UE4资源加载和缓存的整体流程进行了分析,这样可以对整个UE4资源管理流程有更深入的了解,同时也 ...
- FreeRTOS系列第19篇---FreeRTOS信号量
来自:http://blog.csdn.net/zhzht19861011/article/details/50835613 本文介绍信号量的基础知识,详细源码分析见<FreeRTOS高级篇6- ...
- FreeRTOS中断管理
嵌入式实时系统需要对整个系统环境产生的事件作出反应.这些事件对处理时间和响应时间都有不同的要求.事件通常采用中断方式检测,中断服务例程(ISR)中的处理量应当越短越好. 注意:只有以" ...
- UE4 项目优化经验(性能、资源管理、打包等优化)
UE4 优化(性能.资源管理.打包等优化) 一.如何查看性能指标 二.性能优化的方式 优化帧率 优化UE4项目启动速度 优化打包速度和缩小包容量 采用Jenkins进行持续集成交付 删除不用资源 三. ...
- UE4让物体始终朝向摄像机(二)—RInterp To用法
在<UE4让物体始终朝向摄像机(一)-Find Look At Rotation用法>中,我们已经实现了让物体始终朝向我们的摄像机.在这篇文章中,我们再介绍一个新的节点RInterp To ...
- UE4材质、蓝图节点及用法笔记
本文章作为博主本人学习和记录UE4材质节点使用,并与大家交流分享,不定期更新. 目录 材质基础节点 Saturate DepthFade Frac BlendMaterialAttributes Cu ...
- UE4 使用UAssetManager进行资源的异步加载
加载资源的主要代码 void AMyAssetLoadManager::DoAsyncLoadAssetList() { UAssetManager &AssetManager = UAsse ...
最新文章
- 如何用git连接mysql_phpstorm神器之连接使用GitMySQL
- fiddler无法抓取chrome浏览器请求的解决方案之关闭代理软件
- python利器的使用-图文详解python开发利器之ulipad的使用实践
- validator API文档
- win7 64位下如何安装配置mysql-5.7.4-m14-winx64(安装记录)
- 黑科技揭秘:3分钟,轻松构建一张覆盖全球的企业专有网络
- python该怎样使用_Python 应该怎么去练习和使用?
- struts2令牌(token)内部原理
- MyBatis知识点学习
- BZOJ3028 食物
- log4j:WARN Please initialize the log4j system properly解决办法
- 回调函数 EnumFontFamProc
- 计算机组成原理(微课版)谭志虎pdf资源
- 惠普打印机换硒鼓图解_hp硒鼓怎么安装 hp硒鼓安装方法这图文教程】
- Androd 基本布局(其一)
- 编译 pg_repack
- Android 网络框架 Retrofit2.0介绍、使用和封装
- Android中文API(129) —— AudioManager
- iTop4412 Booting Sequence
- 解决导出Excel后0丢失的问题