Unity3D中Newtonsoft.Json序列化优化策略
前言
在Unity3D中使用Newtonsoft.Json(http://Json.NET)进行序列化时,可以通过以下策略进行优化,提升性能和减少内存开销:
对惹,这里有一个游戏开发交流小组,希望大家可以点击进来一起交流一下开发经验呀!
1. 避免重复创建序列化设置
每次序列化都创建新的 JsonSerializerSettings
会产生GC开销。推荐缓存设置:
private static readonly JsonSerializerSettings _settings = new JsonSerializerSettings {ReferenceLoopHandling = ReferenceLoopHandling.Ignore, // 忽略循环引用NullValueHandling = NullValueHandling.Ignore, // 忽略null值DefaultValueHandling = DefaultValueHandling.Ignore, // 忽略默认值Formatting = Formatting.None // 无格式化(最小体积)
};// 使用缓存设置
string json = JsonConvert.SerializeObject(obj, _settings);
2. 使用流式API处理大文件
直接读写文件流,避免一次性加载大JSON字符串:
// 序列化到文件
using (StreamWriter sw = new StreamWriter("data.json"))
using (JsonWriter writer = new JsonTextWriter(sw)) {JsonSerializer.CreateDefault(_settings).Serialize(writer, data);
}// 从文件反序列化
using (StreamReader sr = new StreamReader("data.json"))
using (JsonReader reader = new JsonTextReader(sr)) {var data = JsonSerializer.CreateDefault(_settings).Deserialize<MyDataType>(reader);
}
3. 减少序列化数据量
- 选择性序列化:使用
[JsonIgnore]
标记不需要的属性:
public class PlayerData {public string Name { get; set; }[JsonIgnore]public Vector3 Position; // Unity类型默认不支持,需自定义Converter
}
自定义ContractResolver:动态控制序列化字段:
public class IgnoreVectorResolver : DefaultContractResolver {protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization) {JsonProperty property = base.CreateProperty(member, memberSerialization);if (property.PropertyType == typeof(Vector3)) {property.ShouldSerialize = _ => false; // 跳过所有Vector3}return property;}
}// 使用
_settings.ContractResolver = new IgnoreVectorResolver();
4. 为Unity类型编写自定义Converter
Newtonsoft默认不支持Unity的 Vector3、Color 等类型。自定义Converter示例:
public class Vector3Converter : JsonConverter<Vector3> {public override void WriteJson(JsonWriter writer, Vector3 value, JsonSerializer serializer) {writer.WriteStartArray();writer.WriteValue(value.x);writer.WriteValue(value.y);writer.WriteValue(value.z);writer.WriteEndArray();}public override Vector3 ReadJson(JsonReader reader, Type objectType, Vector3 existingValue, bool hasExistingValue, JsonSerializer serializer) {float[] array = serializer.Deserialize<float[]>(reader);return new Vector3(array[0], array[1], array[2]);}
}// 注册Converter
_settings.Converters.Add(new Vector3Converter());
5. 优化序列化深度和复杂对象
- 限制最大深度(防堆栈溢出):
_settings.MaxDepth = 64; // 根据需求调整
拆分复杂对象:将大对象拆分为多个子对象分别序列化。
6. 预编译序列化器(AOT平台)
针对IL2CPP(如iOS):避免AOT编译错误并提升性能:
- 生成预编译序列化器:
// 在Editor中运行此代码生成
var myTypes = new[] { typeof(PlayerData), typeof(Inventory) /* 其他类型 */ };
var settings = new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Auto
};
Newtonsoft.Json.Utilities.AotHelper.EnsureList(myTypes); // 触发预编译
将生成的 Newtonsoft.Json_*.dll
放入Plugins目录。
7. 性能关键代码使用StringBuilder
高频小对象序列化时,用 StringBuilder
减少字符串拼接开销:
StringBuilder sb = new StringBuilder(256); // 预分配内存
using (StringWriter sw = new StringWriter(sb))
using (JsonWriter writer = new JsonTextWriter(sw)) {JsonSerializer.CreateDefault(_settings).Serialize(writer, obj);
}
string json = sb.ToString();
8. 避免频繁序列化
- 增量更新:只序列化变化的部分(如使用JSON Patch)。
- 对象池:复用反序列化后的对象。
9. 替代方案:System.Text.Json(Unity 2021.2+)
如果项目允许,切换到Unity支持的 System.Text.Json
(性能更高,GC更低):
using System.Text.Json;string json = JsonSerializer.Serialize(obj, new JsonSerializerOptions {IgnoreNullValues = true,WriteIndented = false
});
关键注意事项
- 循环引用:确保设置
ReferenceLoopHandling.Ignore
。 - Unity版本兼容:
- Newtonsoft需通过Package Manager安装(包名:
com.unity.nuget.newtonsoft-json
)。 - 旧版本Unity需手动导入
.dll
。
- IL2CPP问题:提前测试AOT平台,使用预编译序列化器。
通过以上优化,可显著降低序列化开销(尤其是GC和CPU耗时),特别适合移动设备或高频序列化场景(如网络通信、存档系统)。
更多教学视频
Unity3Dwww.bycwedu.com/promotion_channels/2146264125