创新网站建设工作室做百度推广的网络公司
一. Uboject的官方文档的个人理解
Objects in Unreal Engine | 虚幻引擎 5.5 文档 | Epic Developer Community
目录在此
1.垃圾回收:上篇文章简单介绍过,UObject的创建和回收。本身是很复杂的功能,后续会接着单项深入分析。
2.引用更新
1. 反射:之前的文章描述过的CDO,还有就是C++与蓝图相互调用UFUCTION,UPROPERTY。
2.序列化:编辑器的资产序列化到磁盘上,变为.uasset等格式的资产文件。所有的东西存在编辑器里,都是UObject,它们通过Serialize()进行里的序列化操作。
3.默认属性值自动更新:属性值你改过,就以你改过为准。你没改过,它就是默认属性值。你在代码里改过默认属性值,则所有没改过的属性值都会跟着改。
4.自动属性初始化:所有UPROPERTY下的属性值,如果自己不初始化,则会自动初始化,就是int ,float 会初始化0,字符串会初始化为空串。
5.运行时类型信息可用:做类型转换的判定,is,as的关系
6.网络复制:有些属性要从服务器同步过来,就需要UPREPERTY里的元数据replitic。
USTRUCT 大部分都有,它有着和UObject一样的反射和序列化能力。USTRUCT会被当做数值类型处理,而且而且不会被GC掉。
UObject不具备每帧更新的能力,在必要时可以使用inherites类说明符从 FTickableGameObject继承即可添加此能力,拥有Tick()。
二. 头文件
一般都会包含那几个,头文件和宏。用多了自然就记住了
#pragma once#include 'Object.h'#include 'MyObject.generated.h'UCLASS()class MYPROJECT_API UMyObject : public UObject{GENERATED_BODY()};
官方文档,很详细。就不多说了。
三.UObject的销毁
我一般都是Destroy销毁,和 IsValid()判断是否有效,不为空,没被回收。由于对智能指针运用不纯熟,再不写,后续有更深入的理解。会再补上。大家自行看文档。
四.NewObject
是最简单的UObject工厂方法。它接受一个可选的外部对象和类,并用自动生成的名称创建一个新实例,这里直接看引擎源码
#if DO_CHECK
/** Called by NewObject to make sure Child is actually a child of Parent */
COREUOBJECT_API void CheckIsClassChildOf_Internal(const UClass* Parent, const UClass* Child);
#endif/*** Convenience template for constructing a gameplay object** @param Outer the outer for the new object. If not specified, object will be created in the transient package.* @param Class the class of object to construct* @param Name the name for the new object. If not specified, the object will be given a transient name via MakeUniqueObjectName* @param Flags the object flags to apply to the new object* @param Template the object to use for initializing the new object. If not specified, the class's default object will be used* @param bCopyTransientsFromClassDefaults if true, copy transient from the class defaults instead of the pass in archetype ptr (often these are the same)* @param InInstanceGraph contains the mappings of instanced objects and components to their templates* @param ExternalPackage Assign an external Package to the created object if non-null** @return a pointer of type T to a new object of the specified class*/
template< class T >
FUNCTION_NON_NULL_RETURN_STARTT* NewObject(UObject* Outer, const UClass* Class, FName Name = NAME_None, EObjectFlags Flags = RF_NoFlags, UObject* Template = nullptr, bool bCopyTransientsFromClassDefaults = false, FObjectInstancingGraph* InInstanceGraph = nullptr, UPackage* ExternalPackage = nullptr)
UObject* Outer, const UClass* Class, FName Name = NAME_None, EObjectFlags Flags = RF_NoFlags, UObject* Template = nullptr, bool bCopyTransientsFromClassDefaults = false, FObjectInstancingGraph* InInstanceGraph = nullptr, UPackage* ExternalPackage = nullptr
Outer是对象。新的外部对象。如果未指定,对象将在临时包中创建Class。有没有外部的内存接住,没有就临时内存。
Class,是指要构造的对象。
Flags 应用于新对象的对象标志。就是说Object有哪些特性。
Template 初始化新特性,没有的话就用CDO初始化
UCameraComponent* tmpComp = NewObject<UCameraComponent>(Cast<UObject>(this), baseClass, *it.CameraName);
比SpawnActor简单不少。
五.对象标记
对象标记
EObjectFlags
枚举用于快速而简洁地描述对象。有各种各样的标志来描述对象的类型、垃圾收集如何处理它、对象在其生命周期中所处的阶段等等。还有特殊的全掩码或无掩码和预定义的标记组。
理解:通过位运算来,确认有哪些特性。一个位都包含多个特性,就像在游戏里也经常来位。进行状态判断。
六.虚幻Object处理
说一些我觉得有意思的。
请注意,这不意味着所有UObject*
变量都必须是UProperties
。如果你需要的Object指针不是UProperty
,请考虑使用TWeakObjectPtr
。这是"弱"指针,意味着不会妨碍垃圾回收,但可以查询有效性,然后再接受访问,并且它所指向的Object要被销毁时,它将被设置为空。
更可靠,但不用UProperties,TWeakObjectPtr也可以可靠,稳定内存不会有问题。
序列化:
当UObject
被序列化时,所有UProperty
值都将被自动写入或读取,除非显式标记为"瞬时"或无法从后构造函数默认值进行更改。例如,你可以在关卡中放入AEnemy
实例,将其"体力(Health)"设置为500,保存并成功地重新加载,而不必在UClass
定义之外编写一行代码。
当添加或删除UProperties时,系统会无缝处理加载预先存在的内容。新属性从新的CDO复制默认值。删除的属性将会被静默忽略。
如果需要自定义行为,则可以覆盖UObject::Serialize
函数。这对于检测数据错误,检查版本号或执行自动转换或更新(如果数据格式有所更改)十分有用。
UObject直接通过uasset读取信息,不需要读表之类的操作。
网络复制一般有两种同步,一种是从服务器同步到客户端。另一种RTC,客户端呼叫服务器执行,服务器呼叫客户端执行,用到了UPROPERTY,UFUNCTION 同步UObject。
RPC本质上是一次简单的请求,即一次性的数据传输。RPC具有主动性,可以在客户端和服务器之间发起主动通信。
七.TSubClassOf
可以简单理解为蓝图C++中关于UClass类的通信方式,还强制了派生类的限定。当然UClass最底层还是继承UObject
TSubclassOf 是提供 UClass 类型安全性的模板类。例如您在创建一个投射物类,允许设计者指定伤害类型。您可只创建一个 UClass 类型的 UPROPERTY,让设计者指定派生自 UDamageType 的类;或者您可使用 TSubclassOf 模板强制要求此选择.
八.类说明符
类说明符 | 虚幻引擎 5.5 文档 | Epic Developer Community
小心MiniAPI,无法被调用。