2种引用方式

硬引用(Hard Reference)

即对象 A 引用对象 B,并导致对象 B 在对象 A 加载时加载

  • 硬引用过多会导致运行时很多暂时用不到的资源也被加载到内存中
  • 大量资源会导致进程阻塞,致使程序情动事件过长
  • 用不大的资源也在内存中,会占用内存

软引用(Soft Reference)

即对象 A 通过间接机制(例如字符串形式的对象路径)来引用对象 B

  • 软引用可以减少加载负担,可以缩短程序启动时间
  • 软引用不会主动加载到内存中,在需要时加载,用完释放

蓝图中的资源引用

C++ 中资源的硬引用

直接属性引用

引用资源的最简单方法是创建指针,并通过 UPROPERTY 宏公开。这样允许设计人员通过蓝图继承对原型指定特定资源,或通过放在环境中的实例来指定该资源

UPROPERTY(VisibleAnywhere)
UStaticMeshComponent* body; UPROPERTY(VisibleAnywhere)
class UPhysicsThrusterComponent* upThrusterComp; //class 不需要添加对应头文件,cpp使用时再添加

TSubclassOf 与 UClass

TSubclassOf 与 UClass 类似,但 TSubclassOf 是安全类型,同时具有筛选功能,

UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Class")
UClass* ClassRef; UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Class")
TSubclassOf<AActor> ActorClassRef; // 获取UClass* 指针
ClassRef = ActorClassRef.Get();

构造时引用

  • **ConstructorHelpers::FObjectFinder<T>** 一般用来加载非蓝图资源

  • **ConstructorHelpers::FClassFinder<T>** 一般用来加载蓝图资源并获取蓝图Class

    • 蓝图文件路径_C,如 Blueprint'/Game/CPPFunction/Load/BP_MyActor.BP_MyActor_C'

    • 蓝图文件去掉后缀,如 Blueprint'/Game/CPPFunction/Load/BP_MyActor'

  • FObjectFinder 和 FClassFinder构造函数都是调用LoadObject()

  • 只能在类的构造函数中使用,否则会crash

  • 变量名必须是 static 类型,也可以使用 auto

// 构造函数
// FObjectFinder 方法一
auto paddleMesh = ConstructorHelpers::FObjectFinder<UStaticMesh>(TEXT("StaticMesh'/Game/Demo_Drone/SM/paddle.paddle'"));
if (paddleMesh.Object != nullptr)
{
paddle1->SetStaticMesh(paddleMesh.Object);
} //FObjectFinder 方法二
static ConstructorHelpers::FObjectFinder<UStaticMesh> paddleMesh(TEXT("StaticMesh'/Game/Demo_Drone/SM/paddle.paddle'"));
if (paddleMesh.Succeeded())
{
paddle1->SetStaticMesh(paddleMesh.Object);
} // FClassFinder
static ConstructorHelpers::FClassFinder<AActor> BPClassFinder(TEXT("Blueprint'/Game/CPPFunction/Load/BP_MyActor'"));
if (BPClassFinder.Succeeded()) //或者使用 BPClassFinder.Class != nullptr 判断
{
UClass* MyActorClass = BPClassFinder.Class.Get();
TSubclassOf<AActor>BP_MyActorClass = BPClassFinder.Class;
UE_LOG(LogTemp, Warning, TEXT("class name:%s"),*BP_MyActorClass->GetName());
}

C++ 中资源的软引用

  • 间接引用并不存放资源本身,本章节主要介绍 FSoftObjectPathFSoftClassPathTSoftObjectPtr
  • 使用用这种方式需要手动加载资源(同步/异步加载:LoadObject, StaticLoadObject, FStreamingManager)

FSoftObjectPath

  • FSoftObjectPath 是一个简单的结构体,其中有一个字符串包含资源的完整名称。

  • FSoftObjectPath.SolveObject() 可以检查其引用的资源是否已经载入在内存中,若载入则返还资源对象指针,否则返还空。

  • FSoftObjectPath.Reset() 重置软引用为空

  • AllowedClasses meta标签可以筛选资源类型

    • 筛选自定义类 类型时,只能指定放置在 level 中的物体实例,不推荐
// .h 文件
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "SoftObject", meta = (AllowedClasses = "SkeletalMesh, StaticMesh" ))
FSoftObjectPath SoftObjectPath1; UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "SoftObject", meta = (AllowedClasses = "Texture2D"))
FSoftObjectPath SoftObjectPath2; UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "SoftObject", meta = (AllowedClasses = "Blueprint Class"))
FSoftObjectPath SoftObjectPath3; UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "SoftObject", meta = (AllowedClasses = "Drone")) //自定义类型 不推荐
FSoftObjectPath SoftObjectPath4;
// .cpp文件
void ADrone::BeginPlay()
{
Super::BeginPlay(); if (SoftObjectPath1.IsValid()){ /* 处理*/ }
if (SoftObjectPath2.IsNull()){ /* 处理*/ }
if (SoftObjectPath3.IsAsset()){ /* 处理*/ }
FString SoftObjectPath4_AssetName = SoftObjectPath4.GetAssetName();
FString SoftObjectPath3_AssetPath = SoftObjectPath3.GetAssetPathString();
}

FSoftClassPath

  • FSoftClassPath 继承自 FSoftObjectPath,用于存储一个类型的软引用

  • MetaClass meta标签可以筛选类类型

  • FSoftClassPath 继承自 FSoftObjectPath,因此用法与 FSoftObjectPath 差不多

// .h 文件
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "SoftObjectClass")
FSoftClassPath SoftClassPath; UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "SoftObjectClass", meta = ( MetaClass= "Pawn"))
FSoftClassPath SoftClassPath_Pawn; UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "SoftObjectClass", meta = (MetaClass = "Drone"))
FSoftClassPath SoftClassPath_Drone;

TSoftObjectPtr<T>

  • TSoftObjectPtr 基本上是包含了 FSoftObjectPath 的 TWeakObjectPtr,是智能指针的一种

  • TSoftObjectPtr 与蓝图中的 SoftObjectReference 是一回事

  • 可用于在异步加载完成触发回调函数时,获取资源对应的对象指针

  • TSoftObjectPtr.IsPending() 方法可检查资源是否已准备好可供访问

  • TSoftObjectPtr.Get() 如果被引用资源存在于内存中,将返回这个资源

// .h 文件
// 目前使用4.26,不加 <T> 编译不通过
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "SoftObjectPtr")
TSoftObjectPtr<UObject> SoftObjectPtr1; UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "SoftObjectPtr")
TSoftObjectPtr<UObject> SoftObjectPtr2; UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "SoftObjectPtr")
TSoftObjectPtr<UTexture2D> SoftObjectPtr_Texture2D;
// .cpp 文件 BeginPlay() 函数内
SoftObjectPtr2 = TSoftObjectPtr<AActor>(SoftObjectPath3); //可用 FSoftObjectPath 参数初始化 //此处资源未加载,因而判断为false
if (SoftObjectPtr_Texture2D.IsPending())
{
//获取资源
UTexture2D* MyTexture = SoftObjectPtr_Texture2D.Get();
} //转换成 FSoftObjectPath
FSoftObjectPath AActorSoftPath1 = SoftObjectPtr_Texture2D.ToSoftObjectPath();

TSoftClassPtr<T>

  • 获取类的软引用,转成 UClass*
// .h
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "SoftClassPtr")
TSoftClassPtr<AActor> SoftClassPtr_Actor; UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "SoftClassPtr")
TSoftClassPtr<ADrone> SoftClassPtr_Drone; UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "SoftClassPtr")
TSoftClassPtr<UUserWidget> SoftClassPtr_UserWidget;
// .cpp 

if (SoftClassPtr_Actor.IsPending())
{
UClass* MyActor = SoftClassPtr_Actor.Get();
}

参考

【UE4 C++ 基础知识】<10>资源的引用的更多相关文章

  1. 【UE4 C++ 基础知识】<11>资源的同步加载与异步加载

    同步加载 同步加载会造成进程阻塞. FObjectFinder / FClassFinder 在构造函数加载 ConstructorHelpers::FObjectFinder Constructor ...

  2. 【UE4 C++ 基础知识】<3> 基本数据类型、字符串处理及转换

    基本数据类型 TCHAR TCHAR就是UE4通过对char和wchar_t的封装 char ANSI编码 wchar_t 宽字符的Unicode编码 使用 TEXT() 宏包裹作为字面值 TCHAR ...

  3. 【UE4 C++ 基础知识】<12> 多线程——FRunnable

    概述 UE4里,提供的多线程的方法: 继承 FRunnable 接口创建单个线程 创建 AsyncTask 调用线程池里面空闲的线程 通过 TaskGraph 系统来异步完成一些自定义任务 支持原生的 ...

  4. 深度学习FPGA实现基础知识10(Deep Learning(深度学习)卷积神经网络(Convolutional Neural Network,CNN))

    需求说明:深度学习FPGA实现知识储备 来自:http://blog.csdn.net/stdcoutzyx/article/details/41596663 说明:图文并茂,言简意赅. 自今年七月份 ...

  5. 【UE4 C++ 基础知识】<5> 容器——TArray

    概述 TArray 是UE4中最常用的容器类.其速度快.内存消耗小.安全性高. 其设计时未考虑扩展问题,因此建议在实际操作中勿使用 新建(new) 和 删除(delete) 创建或销毁 TArray ...

  6. 【UE4 C++ 基础知识】<6> 容器——TMap

    概述 TMap主要由两个类型定义(一个键类型和一个值类型),以关联对的形式存储在映射中. 将数据存储为键值对(TPair<KeyType, ValueType>),只将键用于存储和获取 映 ...

  7. 【UE4 C++ 基础知识】<8> Delegate 委托

    概念 定义 UE4中的delegate(委托)常用于解耦不同对象之间的关联:委托的触发者不与监听者有直接关联,两者通过委托对象间接地建立联系. 监听者通过将响应函数绑定到委托上,使得委托触发时立即收到 ...

  8. C# 篇基础知识10——多线程

    1.线程的概念 单核CPU的计算机中,一个时刻只能执行一条指令,操作系统以“时间片轮转”的方式实现多个程序“同时”运行.操作系统以进程(Process)的方式运行应用程序,进程不但包括应用程序的指令流 ...

  9. 【UE4 C++ 基础知识】<2> UFUNCTION宏、函数说明符、元数据说明符

    UFunction声明 UFunction 是虚幻引擎4(UE4)反射系统可识别的C++函数.UObject 或蓝图函数库可将成员函数声明为UFunction,方法是将 UFUNCTION 宏放在头文 ...

随机推荐

  1. 史上最详细的信号使用说明(已被收藏和N次)

    Unix环境高级编程(第三版) 第10章 信号 文章目录 1. 引言 2. 信号的概念 2.1 信号操作之忽略信号 2.2 信号操作之捕捉信号 2.3 信号操作之执行系统默认操作 2.4 常见的信号 ...

  2. 事务保存点savepoint

    一.

  3. (6)java Spring Cloud+Spring boot+mybatis企业快速开发架构之SpringCloud-Spring Boot项目详细搭建步骤

    ​ 在 Spring Tools 4 for Eclipse 中依次选择 File->New->Maven Project,然后在出现的界面中按图所示增加相关信息. ​ <paren ...

  4. Tars | 第2篇 TarsJava SpingBoot启动与负载均衡源码初探

    目录 前言 1. Tars客户端启动 @EnableTarsServer 2. Communicator通信器 3. 客户端的负载均衡调用器LoadBalance 最后 前言 通过源码分析可以得出这样 ...

  5. modern php closure 闭包

    * 在array_map()函数中使用闭包 <?php $numbersPlusOne = array_map(function($number) { return $number + 1; } ...

  6. kibana操作

    一些KIBANA的操作,记录下,免下次重复写 #创建索引名为kb_question的索引,并添加mapping,即各字段属性 PUT kb_question { "mappings" ...

  7. vm 将宿主机文件夹 映射至 虚拟机

    一.关于centos如何安装(自行百度) 二.设置共享文件夹 添加共享文件夹(关闭虚拟机时操作) 虚拟机->设置->选项->共享文件夹 三.安装vm-tools (请用root用户执 ...

  8. P5012-水の数列【并查集,RMQ】

    正题 题目链接:https://www.luogu.com.cn/problem/P5012 题目大意 \(n\)个数字的一个序列,\(T\)次询问给出\([l,r]\)要求 找出一个最大的\(x\) ...

  9. JPA自动生成表

    一句话总结: 在配置文件中 jpa-hibernate-ddl-auto:update validate 加载 Hibernate 时,验证创建数据库表结构 create 每次加载 Hibernate ...

  10. Python3入门系列之-----return返回值,我终于懂了

    前言 初学者学习return的用法有点蒙,不知道它的作用是什么?返回的是什么?在什么时候要用?小伙伴也可能会遇到和我同样的困扰,给大家举个例子,马上就明白了. 同一段代码,函数中带return和没有r ...