Skip to content

序列化系统

序列化系统提供对属性和资源的持续化保存。使得开发者可以对场景物体位置,属性进行改变。

序列化系统包括了项目整个场景的保存,用户也可以根据需要保存并读取Object,对于自定义创建的脚本,也可以配置所需的属性进行序列化保存。

场景的序列化保存

在引擎的视图编辑器中,编辑场景中的物体属性,并进行保存。

场景编辑

打开引擎后,在打开的编辑界面,可以查看到场景中的物体。 alt text 在编辑器界面,用户可以改变场景中物体的位置,挂载脚本,脚本属性,并且可以添加或者删除新的对象。

编辑完成后,点击保存场景或使用Ctrl+S快捷键可以对改动进行保存,保存成功后将出现提示弹窗。

场景文件查看

场景编辑完毕后,用户可以通过查看Scene.nscene文件检查和确保保存数据正确性。 alt text 在Assets的场景文件夹中,选择Scene文件夹,打开所在文件夹,我们就可以在资源管理器中查看当前场景的场景文件。

使用文本打开场景文件: alt text 打开的场景文件,记录了场景里所有物体的位置变换,挂载脚本,脚本中序列化属性等信息。 alt text

预制体使用

在开发过程中,预制体(Prefab)是一种非常重要的资源,它允许开发者创建、配置和存储游戏对象及其所有组件、属性值和子游戏对象作为可重用的模板。预制体的主要作用是为了重复利用资源,例如游戏世界中的花草树木、房屋建筑等。这些资源通常会在游戏中多次出现,通过将它们转换为预制体,可以方便地在不同的场景中重复使用。 alt text 进入场景管理界面,选择预制体选项,便可以在文件管理的资源/预制体 界面寻找到生成的预制体。 alt text 生成的预制体可以直接通过拖动到场景中进行加载,也可以通过代码在运行时动态加载至场景中。

  • 使用代码加载预制体:
cpp
	NActorList ActorList=NAssetManager::LoadPrefabFromFile("Assets/Prefabs
	/NewPrefab.prefab");
	NActorPtr Actor = ActorList[0];
	NActorManager::AddActors(ActorList);
	m_comp player = Actor->GetComponent<PlayerCtrl>();
	player->InitPlayer();

脚本属性序列化

对于自定义脚本中的属性,在使用反射将其更改后,往往需要将其持久化至运行时阶段。对此,我们需要将所需的属性进行序列化处理。

序列化宏说明: 对于基础变量,例如引擎Actor指针或组件指针,共享指针:

指针说明
SERIALIZE()默认序列化宏,采用深拷贝保存变量
SERIALIZE_WITH_NAME()采用深拷贝保存变量,并且单独命名
SERIALIZE_REF()采用浅拷贝保存变量
SERIALIZE_REF_WITH_NAME()采用浅拷贝保存变量,并且单独命名
对于继承Object的对象指针:
指针说明
SERIALIZE_OBJECT_PTR默认序列化宏,采用深拷贝保存变量
SERIALIZE_OBJECT_PTR_WITH_NAME采用深拷贝保存变量,并且单独命名
SERIALIZE_OBJECT_PTR_REF采用浅拷贝保存变量
SERIALIZE_OBJECT_PTR_REF_WITH_NAME采用浅拷贝保存变量,并且单独命名
对于枚举类:
枚举说明
SERIALIZE_ENUM默认序列化宏
SERIALIZE_ENUM_WITH_NAME序列化并单独命名

如果要序列化非继承object对象,首先需要重写对象的<<操作符注意类型参数为引用, 例如: friend Archive& operator << (Archive& ar, Type& data) 后使用:SERIALIZE_T或SERIALIZE_T_WITH_NAME序列化该对象 注意使用SERIALIZE_T需要传入类型参数

如果要序列化非继承object对象的指针,同样需要重写对象的<<操作符。并且参数类型采用指针类型。 后使用:SERIALIZE_T_PTR或SERIALIZE_T_PTR_WITH_NAME序列化该对象

代码示例:

cpp
	REFLECTION_BEGIN(NewScript1)
	// add your variable reflection property
	//Enum Class Name, Display Name In Editor, Variable Name In Class, flags default is 0
	//ENUM_PROPERTY(LabelType, Type, m_LabelType, 0)
	PROPERTY(TestNum, TestNum, 0)
	//PROPERTY(Rotate, m_EnableRotate, 0)
	//FUNCTION(OnButtonClick, NewScript1, OnClick)
	REFLECTION_END
	void NewScript1::Serialize(Archive& ar)
	{
		Super::Serialize(ar);
		SERIALIZE(TestNum);
	}
	void NewScript1::Update()
	{
		NDebug::Log("m_Num =%d", TestNum);
		// Called every frame if actor is enabled.
	}

将int属性反射(详情见反射系统),并序列化后。场景里挂载脚本即可修改该变量值。

alt text 反射完毕后,修改该值便可在运行时获取持久化后的变量。