How to serialize vector3 with JSON.net?

Hi,

I’m trying to serialize vector3 fields using JSON.net, however, it’s also serializing normalized values and magnitudes, e.g.:

{
          "x": -0.139040321,
          "y": -0.0536295325,
          "z": -0.250134617,
          "normalized": {
            "x": -0.47753495,
            "y": -0.184191,
            "z": -0.8590891,
            "magnitude": 1.0,
            "sqrMagnitude": 1.0
          },
          "magnitude": 0.2911626,
          "sqrMagnitude": 0.0847756639
        }

I know you can use attributes to specify which fields/properties should be included for serialization, but since I don’t own this type that doesn’t seem like a viable approach.

Is anyone using JSON.net to serialize just the xyx components of vector3? If so how?

Thank you

In Unity 2020.1 Alpha, I managed to get Newtonsoft.Json through the Unity package manager. I customized its serialization by inheriting from DefaultContractResolver and creating a JsonConverter.

  • The custom DefaultContractResolver makes the serialization work just like Unity’s serializer.
  • The JsonConverter gives us the power to decide how many decimal places ALL floats will serialize with.

I describe it and posted the code on the Unity forums.

Not sure if the OP found a solution, but I was getting this same error. I decided to just create a Vector3Json object with just x, y, z properties. When saving the objects, I would create this object from the Vector3 and serialize.


    public void Awake()
    {   
        SurrogateSelector surrogateSelector = new SurrogateSelector();
        surrogateSelector.AddSurrogate(typeof(Vector3), new StreamingContext(StreamingContextStates.All), new Vector3SerializationSurrogate());
        surrogateSelector.AddSurrogate(typeof(Vector3Int), new StreamingContext(StreamingContextStates.All), new Vector3IntSerializationSurrogate());
        Helper.BinaryFormatter.SurrogateSelector = surrogateSelector;
    }

public class Vector3SerializationSurrogate : ISerializationSurrogate
{
    public void GetObjectData(object obj, SerializationInfo info, StreamingContext context)
    {
        Vector3 v3 = (Vector3)obj;
        info.AddValue("x", v3.x);
        info.AddValue("y", v3.y);
        info.AddValue("z", v3.z);
    }

    public object SetObjectData(object obj, SerializationInfo info, StreamingContext context, ISurrogateSelector selector)
    {
        Vector3 v3 = (Vector3)obj;
        v3.x = (float)info.GetValue("x", typeof(float));
        v3.y = (float)info.GetValue("y", typeof(float));
        v3.z = (float)info.GetValue("z", typeof(float));
        return v3;
    }
}


    public static void SaveSetPieceFile(SerializableChunk setPiece, string fileName)
    {
        string json = JsonConvert.SerializeObject(setPiece, new JsonSerializerSettings
        {
            TypeNameHandling = TypeNameHandling.Auto
        });
        string path = Path.Combine(Application.dataPath, "Resources/Set", fileName + ".json");
        File.WriteAllText(path, json);
    }

    public static SerializableChunk LoadSetPieceFile(string fileName)
    { 
        TextAsset textAsset = Resources.Load<TextAsset>("Set/" + fileName);
        return JsonConvert.DeserializeObject<SerializableChunk>(textAsset.text, new JsonSerializerSettings
        {
            TypeNameHandling = TypeNameHandling.Auto
        });
    }