Unreal 序列化版本控制

本文介绍Unreal如何在项目升级时处理旧版本数据,通过FXXXCustomVersion结构定义版本并确保序列化操作的兼容性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题:

  • 前一个版本进入序列化的数据,下一个版本不需要了
  • 下一个版本加了序列化数据,但是上一个版本的文件内没有这个数据

Unreal支持在序列化的时候,获取旧的文件所在的版本号,和新的版本号。可以拿这两个版本号,进行序列化定制。

为对象新建特定的版本管理:

#pragma once

#include "CoreMinimal.h"
#include "Misc/Guid.h"

struct FXXXCustomVersion
{
	enum Type
	{
		// Before any version changes were made
		BeforeCustomVersionWasAdded = 0,
		
		SomeDetailOfVersion1 = 1,
		SomeDetailOfVersion2 = 2,

		// -----<new versions can be added above this line>-------------------------------------------------
		VersionPlusOne,
		LatestVersion = VersionPlusOne - 1
	};

	// The GUID for this custom version number
	const static FGuid GUID;

private:
	FXXXCustomVersion() {}
};
#include "XXXCustomVersion.h"
#include "Serialization/CustomVersion.h"

const FGuid FXXXCustomVersion::GUID(0x1C74D14B, 0x00C145AE, 0x816D0277, 0xA1EA1770);

// Register the custom version with core
FCustomVersionRegistration GRegisterXXXCustomVersion(FXXXCustomVersion::GUID, FXXXCustomVersion::LatestVersion, TEXT("XXXVer"));

GUID随机生成一个就行:只需要和其它版本GUID不一样就好,从概率上来说几乎是不可能重复的
在这里插入图片描述
序列化:

virtual void Serialize(FArchive& Ar) override;

void AXXX::Serialize(FArchive& Ar)
{
	Super::Serialize(Ar);
	Ar.UsingCustomVersion(FXXXCustomVersion::GUID);
	// 判断当前版本(对于Load来说是历史文件的版本号,对于Save来说是最新版本号)
	if (Ar.CustomVer(FXXXCustomVersion::GUID) >= FXXXCustomVersion::SomeDetailOfVersion1)
}

void AXXX::PostLoad()
{
	Super::PostLoad();
	const int32 XXXVer = GetLinkerCustomVersion(FXXXCustomVersion::GUID);
	// 判断加载文件的版本号,做一些历史维护(旧版本移植到新版本)
	if (XXXVer < FXXXCustomVersion::SomeDetailOfVersion1)
}

若之前没有添加版本信息,则读取版本为:BeforeCustomVersionWasAdded也就是0。之后序列化Save的时候,都是保存的当前的LatestVersion值,也就是最新的版本值。所以下次更新版本,版本数++后,读取的旧的LatestVersion值就自然变化了。

<think>好的,用户想了解UE5中JSON序列化的实现或解决方案。首先,我需要回忆UE5的相关文档和API。UE4/UE5通常使用Json模块来处理序列化,可能涉及FJsonObject、FJsonSerializer等类。记得在项目中需要包含Json模块的依赖,比如在Build.cs文件中添加Json和JsonUtilities。 然后,用户可能需要具体的代码示例。例如,如何将UObject序列化为JSON字符串,或者反序列化回来。这时候需要考虑使用FJsonObjectConverter类,它提供了ConvertObjectToJsonObject和ConvertJsonObjectToUObject等方法。但要注意,这些方法可能需要对象标记为BlueprintType,并且属性有适当的UPROPERTY宏。 另外,可能涉及到版本兼容性或自定义序列化的问题。比如处理复杂的数据结构或子对象时,可能需要自定义转换逻辑。还有,用户可能遇到常见的错误,比如字段未正确标记导致序列化失败,这时候需要检查UPROPERTY的设置。 还有引用中的内容,比如引用[3]提到的位掩码操作,可能和序列化无关,但需要确认是否有其他相关信息。不过用户的问题集中在JSON序列化,所以重点应放在UE5的Json模块使用上。 最后,需要提醒用户注意事项,比如模块依赖、属性标记、版本控制等。可能还需要提供一些扩展思路,比如结合数据资产或网络传输的应用场景。这样用户不仅能实现基础功能,还能了解如何优化和应用到实际项目中。</think>在Unreal Engine 5中实现JSON序列化主要通过以下技术方案实现: ### 一、核心实现方案 1. **Json模块基础架构** UE5通过`Json`和`JsonUtilities`模块提供序列化能力,支持`UObject`与JSON格式的相互转换[^1]。需要先在`.Build.cs`文件中添加模块依赖: ```cpp PublicDependencyModuleNames.AddRange(new[] { "Json", "JsonUtilities" }); ``` 2. **对象序列化示例** ```cpp // 序列化UObject到JSON字符串 FString SerializeObject(UMyObject* Obj) { TSharedPtr<FJsonObject> JsonObject; FJsonObjectConverter::UStructToJsonObject(Obj->GetClass(), Obj, JsonObject); TSharedRef<TJsonWriter<>> Writer = TJsonWriterFactory<>::Create(&Result); FJsonSerializer::Serialize(JsonObject.ToSharedRef(), Writer); return Result; } // 反序列化示例 void DeserializeObject(const FString& JsonString) { TSharedPtr<FJsonObject> JsonObject; TSharedRef<TJsonReader<>> Reader = TJsonReaderFactory<>::Create(JsonString); FJsonSerializer::Deserialize(Reader, JsonObject); UMyObject* NewObj = NewObject<UMyObject>(); FJsonObjectConverter::JsonObjectToUStruct(JsonObject.ToSharedRef(), NewObj->GetClass(), NewObj); } ``` ### 二、关键技术细节 1. **属性标记要求** - 需要序列化的属性必须使用`UPROPERTY()`宏 - 建议添加`BlueprintReadWrite`说明符 ```cpp UPROPERTY(BlueprintReadWrite, Category="JSON") FString CharacterName; ``` 2. **自定义类型处理** 通过重载`FJsonObjectConverter::CustomExportCallback`实现: ```cpp FJsonObjectConverter::CustomExportCallback = [](FProperty* Property, const void* Value) -> TSharedPtr<FJsonValue> { if (auto* CustomProp = CastField<FMyCustomProperty>(Property)) { return MakeShared<FJsonValueString>(CustomProp->ToString(Value)); } return nullptr; }; ``` ### 三、常见问题解决方案 | 问题现象 | 解决方案 | |---------|----------| | 序列化时字段丢失 | 检查是否遗漏`UPROPERTY`宏或`BlueprintReadWrite`标记 | | 循环引用导致堆栈溢出 | 使用`ExcludeBaseClass`参数过滤基类属性 | | 自定义结构体无法转换 | 注册类型到`FJsonObjectConverter::RegisterCustomConverter` | ### 四、优化建议 1. **二进制压缩方案** ```cpp // 使用Base64编码压缩 FString Compressed = FBase64::Encode(SerializeObject(Obj)); ``` 2. **异步序列化处理** ```cpp Async(EAsyncExecution::Thread, [Obj](){ FString JsonResult = SerializeObject(Obj); // 发送到网络或保存到磁盘 }); ``` **注意事项:** - 序列化版本控制建议使用`VersionNumber`字段 - 二进制字段需手动进行Base64编解码 - 注意处理`TArray`和`TMap`等容器类型的嵌套序列化 ### 五、调试验证方法 1. 控制台命令: ```bash ConsoleCommand -> Json.Serialize [ClassName] # 实时输出序列化结果 ``` 2. 编辑器扩展: 在蓝图编辑器中添加"Export as JSON"按钮[^3]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值