[UE C++] 资源加载(一) 硬&软引用加载资源

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

[UE C++] 资源加载(一) 硬&软引用加载资源

路径名如何获取

  • 对于对象资源,右键Copy Reference
  • 对于类资源,右键Copy Reference 然后加上 _C

图片来自于 数据驱动开发
c++ 软引用,UE 资源加载,c++,ue4,ue5

1. 硬引用(Hard Reference)加载

概念: 使用硬引用加载方式,当对象A引用对象B,会导致对象B直接被加载到内存当中。若对象B同时硬引用了对象C,那么对象C也会被加载到内存中,这一过程是递归的,可能会导致短时间内存可用容量迅速降低,进而导致进程卡顿。蓝图的 Cast to XXXX 节点会导致硬引用对象,即使存在但不使用该节点也会硬引用cast对象。所以应该避免在蓝图中大量使用该节点

UPROPERTY(EditDefaultsOnly)
UTexture2D* TextureRef;

UPROPERTY(EditDefaultsOnly)
TSubclassOf<AActor> ActorClassRef;

1.1 构造时引用

通过ConstructorHelpers::FXxxxFinder实现,只能在构造函数中使用,注意添加static

//加载对象
static ConstructorHelpers::FObjectFinder<UStaticMeshComponent> DoorMesh(TEXT("StaticMesh'/Game/StarterContent/Props/SM_Door.SM_Door'"));
if (DoorMesh.Succeeded())
{
    DoorMeshHardRef = DoorMesh.Object;
}

//加载类
static ConstructorHelpers::FClassFinder<AActor> ClassFind(TEXT("Blueprint'/Game/Blueprint/BP_Test.BP_Test'"));
if (ClassFind.Succeeded())
{
    ActorClassRef = ClassFind.Class;
}

在以上构造函数中,ConstructorHelpers 类将尝试在内存中查找该资源,如果找不到,则进行加载

1.2 直接属性引用

这是最常见的资源引用情况,将资源通过 UPROPERTY 宏公开。允许设计人员通过蓝图继承对原型指定特定资源,或通过放在环境中的实例来指定该资源

可以和构造时引用一起使用,指定的资源会覆盖构造函数指定的资源
c++ 软引用,UE 资源加载,c++,ue4,ue5

2. 软引用(Soft Reference)加载

概念:

  • 对象A通过间接机制(例如字符串形式的对象路径)来引用对象B,软引用对象并不会主动地将引用对象加载到内存当中,需要手动进行同步/异步加载,即软引用并不存放资源本身
  • 软引用为间接属性引用,间接属性引用的工作方式对于设计人员就像直接属性引用一样(蓝图中下滑菜单进行选取资源),但是,属性以字符串形式与模版代码存储在一起以便安全地检查资源是否已加载,而不是进行直接指针引用

2.1 FSoftObjectPath

软对象路径,内部存在了一个字符串用于保存引用对象的路径

UPROPERTY(EditDefaultsOnly, BlueprintReadOnly)
FSoftObjectPath ObjectSoftRef;

UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, meta = (AllowedClasses = "SkeletalMesh,StaticMesh"))
FSoftObjectPath MeshSoftRef;

注意事项:

  • 可用AllowedClasses筛选引用对象类型,但是对自定义类型进行筛选会出问题
  • AllowedClasses的筛选主要是针对于在Editor中下滑菜单进行选取Object时筛选指定资源,不影响在C++中的使用。换句话说如果AllowedClasses = "SkeletalMesh,StaticMesh",但 MeshSoftRef却指定了一个UTexture2D资源,还是可以正常加载并使用
2.1.1 指定引用对象路径
//通过 = ,对象可是FString,FName,FSoftObjectPath对象等
MeshSoftRef = "SkeletalMesh'/Game/Mannequin/Character/Mesh/SK_Mannequin.SK_Mannequin'";

//通过SetPath
MeshSoftRef.SetPath("SkeletalMesh'/Game/Mannequin/Character/Mesh/SK_Mannequin.SK_Mannequin'");

//通过构造函数
FSoftObjectPath MeshSoftRef{ FString("SkeletalMesh'/Game/Mannequin/Character/Mesh/SK_Mannequin.SK_Mannequin'") };
2.1.2 ResolveObject

作用: 判断其引用的资源是否已经载入在内存中,若载入则返还资源对象指针,否则返还空。

//可能为空
TextureRef = Cast<UTexture2D>(ObjectSoftRef.ResolveObject());
2.1.3 TryLoad

作用: 内部调用LoadObject,尝试在内存中寻找资源,若资源未加载会进行同步加载

//路径未错,会返回UObject指针指向资源
TextureRef = Cast<UTexture2D>(ObjectSoftRef.TryLoad());

2.2 FSoftClassPath

软类路径,继承于 FSoftObjectPath,专门用于对 UClass* 的软引用

UPROPERTY(EditDefaultsOnly, BlueprintReadOnly)
FSoftClassPath ClassSoftRef;

UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, meta = (MetaClass = "Actor"))
FSoftClassPath ActorClassSoftRef;

注意事项:

  • 可用MetaClass筛选类的范围,对于自定义类型可很好的支持
  • MetaClass也只在Editor起作用
2.2.1 指定引用对象路径

由于构造函数和赋值运算符无法继承,所以这里有一点区别存在

//通过构造函数,参数可是UClass,FString,FSoftClassPath
FSoftClassPath ClassSoftRef{"Blueprint'/Game/Blueprint/BP_Test.BP_Test_C'" };

//通过SetPath
ClassSoftRef.SetPath("Blueprint'/Game/Blueprint/BP_Test.BP_Test_C'");
2.2.2 ResolveObject -> ResolveClass
2.2.3 TryLoad -> TryLoadClass

2.3 FSoftObjectPtr

软对象指针,一种指向UObject的弱指针,无法在蓝图中使用,用于异步加载资源过程中,当资源加载完成触发回调函数的时候获取资源对应的对象指针。

FSoftObjectPtr MeshSoftPtr;
struct FSoftObjectPtr : public TPersistentObjectPtr<FSoftObjectPath>
{
    ······
}

FSoftObjectPtr就是继承自TPersistentObjectPtr的智能指针。内部的资源加载逻辑是基于FSoftObjectPath的二次封装,可使用ToSoftObjectPath()返回一个FSoftObjectPath对象

FORCEINLINE const FSoftObjectPath& ToSoftObjectPath() const
{
    return GetUniqueID();
}

但是因为返回的是const FSoftObjectPath&,无法对其引用的资源路径进行修改,只可通过构造函数对其进行初始化指定引用资源路径,或者指定特定UObject对象(CDO对象)

//初始化参数可是UObject,FSoftObjectPath,FSoftObjectPtr
FSoftObjectPtr MeshSoftPtr{ FSoftClassPath {"Blueprint'/Game/Blueprint/BP_Test.BP_Test_C'"}};

注意事项:

  • FSoftObjectPtr不能暴露给蓝图
  • FSoftObjectPtr可以指向UClass,UClass其实就是UObject的子类
  • 内部实际存在了一个指向资源对象的弱指针
2.3.1 Get()

作用: 获得指向资源的UObject指针,若为空不会触发加载

TextureRef = Cast<UTexture2D>(MeshSoftPtr.Get());
2.3.2 IsPending

作用: Test if this does not point to a live UObject, but may in the future

if(!MeshSoftPtr.IsPending())
{
    MeshSoftPtr.Get();
}
2.3.3 IsValid

作用: Test if this points to a live UObject

if(MeshSoftPtr.IsValid())
{
    MeshSoftPtr.Get();
}
2.3.4 LoadSynchronous

作用: 返回指向资源的指针,若资源不存在于内存中则进行同步加载(通过FSoftObjectPath::TryLoad)

TextureRef = Cast<UTexture2D>(MeshSoftPtr.LoadSynchronous());
2.3.5 Reset

作用: Reset the soft pointer back to the null state

MeshSoftPtr.Reset();

2.4 TSoftObjectPtr<>

FSoftObjectPtr的模板化,内部逻辑是基于FSoftObjectPtr的二次封装,可用UProperties公开给蓝图

UPROPERTY(EditDefaultsOnly, BlueprintReadOnly)
TSoftObjectPtr<UTexture2D> TextureSoftPtr;

操作与FSoftObjectPtr基本一致,返回的是指向模板类的指针,减少了手动Cast的步骤

2.5 TSoftClassPtr<>

FSoftObjectPtr的模板化,将其转化为UClass*,可用UProperties公开给蓝图。也可使用TSoftObjectPtr<UClass>这种形式来代替

UPROPERTY(EditDefaultsOnly, BlueprintReadOnly)
TSoftClassPtr<AActor> ClassSoftPtr;

操作与FSoftObjectPtr基本一致,返回的是指向模板类的指针,减少了手动Cast的步骤

软引用关系图

图片来自于 UE4中资源的引用 非本人创作,侵权必删
c++ 软引用,UE 资源加载,c++,ue4,ue5

最后

本文主要介绍了硬引用和软引用,以及软引用其自带的同步加载方式。关于资源的异步加载和更多的同步加载方式,放在下一篇文章来说文章来源地址https://www.toymoban.com/news/detail-717086.html

参考链接

  • 官方-引用资源
  • UE4的资源管理
  • UE4中资源的引用
  • UE4 4.20

到了这里,关于[UE C++] 资源加载(一) 硬&软引用加载资源的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • UE4 UE5学习和资源网站整理

    epic官网 Epic开发 | 首页 - Epic Online Services UE5官方文档 https://docs.unrealengine.com/4.27/zh-CN/j 截屏软件 Snipaste - 截图 + 贴图  Metahuman数字人网站 Epic Games 平面资源网站包图网 包图网_专注原创商用设计图片下载,会员免费设计素材模板独家图库 Artstation外网艺术灵感网站 https://www.ar

    2024年01月21日
    浏览(56)
  • UE5 动态加载资源和类

    因为是动态加载,所以不用在构造的时候去加载。这里再BeginPlay里加载。 加载StaticMesh等资源,就使用LoadObjectUStaticMesh(nullptr,TEXT(\\\"Copy Reference\\\")) 加载类资源,比如蓝图Actor类 就使用LoadClassAActor(this,TEXT(\\\"Copy Reference\\\")) 但是同样要在最后一个字母后+_C  TEXT(\\\"/Script/Engine.Blueprint\\\'/Ga

    2024年02月21日
    浏览(44)
  • 【虚幻引擎UE】UE5 Pak资源分包加密打包与加载(安卓篇)

    【虚幻引擎UE】UE5 Pak分包加密及热更新(安卓篇) 相关文章: 1.介绍了安卓项目打包的基本操作: 【虚幻引擎UE】UE5仅需5个步骤快速实现AR项目调试与打包(安卓篇) https://tjgzs.blog.csdn.net/article/details/126097508 2.介绍了PAK加载的基本操作: 【虚幻引擎UE】UE5 热更新动态PAK资源加

    2024年02月08日
    浏览(50)
  • 【UE4 C++】03-新建UE C++工程,新建C++类

     UE版本:4.26 新建一个空白模板工程,选择C++项目,选择项目名和项目存储位置,然后点击创建项目。 新建C++类  选择父类为Character  命名,选择公有,然后点击创建类  等待编译完成  此时在Visual Studio中可以看到我们刚才创建的类  在UEEditor中新建一个蓝图类,父类为“

    2024年02月16日
    浏览(39)
  • Ue5 C++ metahuman

    参考官网: 创建MetaHuman | Epic Developer Community (epicgames.com) 参考: Quixel Bridge中的MetaHuman | Epic Developer Community (epicgames.com) 参考:导出到虚幻引擎5 | Epic Developer Community (epicgames.com) 参考:在Sequencer中使用MetaHuman | Epic Developer Community (epicgames.com) 待补充

    2024年02月10日
    浏览(49)
  • UE5 C++(十七)— 射线检测

    射线检测简单来说就是通过相机发射一条射线,用来检测对象的一种检测机制。 官网介绍:使用射线进行命中判定 这里主要介绍4种常用的射线检测方式。 关键API: LineTraceSingleByChannel 声明变量 MyCharacter.h 在Tick中实现通道进行射线检测 MyCharacter.cpp 编译 之后,在场景中添加

    2024年01月18日
    浏览(93)
  • ue5 c++ interface 接口

    https://docs.unrealengine.com/5.2/en-US/interfaces-in-unreal-engine/ 1 纯c++ 接口  没有ufunction 2 纯c++ 有ufunction

    2024年02月10日
    浏览(45)
  • UE5 UDP通信 UE4.21-UE5.1

    目录 客户端,发送数据 1.建立字符串变量UDPConnection,绑定连接事件  2.连接初始化  3.发送数据  4.关闭UDP服务  服务器,接收数据 1.绑定连接事件  2.绑定数据接收事件  3.开启UDP服务  4.返回数据  5.关闭UDP服务   需要提供远程端IP地址和端口号 0.0.0.0表示监听所有ip,端口

    2024年02月15日
    浏览(77)
  • 初学UE5,UE4的教程适用UE5吗?

    UE5是最近推出的一款游戏引擎,相较于UE4而言,它有着更好的性能和灵活的工作流程,同时也引入了一些新的功能。对于一些游戏开发初学者来说,他们可能会想知道,是否可以通过UE4的教程来学习UE5。在这里,我们将介绍一下这个问题。 首先,UE5和UE4之间确实存在一些相通

    2024年02月06日
    浏览(53)
  • UE5 C++ UObject实例化

    一.创建UObject C++类  在MyObject中声明结构体FMyDataTableStruct 在MyPawn里面,先将头文件里包含 MyObject.h 在MyPawn中声明一个UMyObject类型的指针 TSubclassOf  是提供 UClass 类型安全性的模板类。例如您在创建一个投射物类,允许设计者指定伤害类型。您可只创建一个 UClass 类型的 UPROPER

    2024年02月21日
    浏览(45)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包