protobuf-net序列化UnityEngine.Vector3字典遇NotSupportedException求助
解决protobuf-net序列化UnityEngine.Vector3集合时的NotSupportedException问题
看起来你在使用protobuf-net序列化包含UnityEngine.Vector3的字典时遇到了默认值检查的坑,这个异常的根源在于:protobuf-net无法正确生成代码判断Vector3是否为默认值——尤其是当你设置了UseImplicitZeroDefaults = false时,严格的默认值检查逻辑会因为Vector3是Unity自定义值类型而失效。
下面针对你尝试的两种注册方式,分别给出修复方案:
方案1:修复显式类型注册
在注册Vector3时,直接跳过该类型的默认值检查,或者为每个字段单独配置:
// 方式一:为整个类型跳过默认值检查 var vector3Meta = serializer.Add(typeof(Vector3), false); vector3Meta.Add(1, "x"); vector3Meta.Add(2, "y"); vector3Meta.Add(3, "z"); vector3Meta.SkipDefaultValueCheck = true; // 方式二:为每个字段单独配置跳过默认值检查 serializer.Add(typeof(Vector3), false) .Add(1, "x", opt => opt.SkipDefaultValueCheck = true) .Add(2, "y", opt => opt.SkipDefaultValueCheck = true) .Add(3, "z", opt => opt.SkipDefaultValueCheck = true);
方案2:修复代理类实现
修改你的SurrogateVector3代理类,为每个序列化字段标记IsRequired = true,这样protobuf-net会认为这些字段是必填项,从而跳过默认值检查:
[ProtoContract] public sealed class SurrogateVector3 { [ProtoMember(1, IsRequired = true)] private float x; [ProtoMember(2, IsRequired = true)] private float y; [ProtoMember(3, IsRequired = true)] private float z; public SurrogateVector3() {} public SurrogateVector3(float x, float y, float z) { this.x = x; this.y = y; this.z = z; } public static implicit operator Vector3(SurrogateVector3 v) { return new Vector3(v.x, v.y, v.z); } public static implicit operator SurrogateVector3(Vector3 v) { return new SurrogateVector3(v.x, v.y, v.z); } }
保持原有的代理注册代码不变即可:
serializer.Add(typeof(Vector3), false).SetSurrogate(typeof(SurrogateVector3));
额外提示
如果你对默认值的严格控制需求不高,也可以尝试暂时启用UseImplicitZeroDefaults = true,让protobuf-net使用零值作为默认值来绕过检查,但这可能不符合你的序列化预期,因此优先推荐上面两种针对性的修复方案。
测试修改后的代码后,序列化Dictionary<int, Vector3>应该就能正常工作了。
内容的提问来源于stack exchange,提问作者Dylan Culfogienis
相关产品推荐
相关产品推荐

