Hello,
I 'm using the Newtonsoft.json to make some saving loading function.
So far it was working, now I get this error :
JsonSerializationException: Self referencing loop detected for property ‘normalized’ with type ‘UnityEngine.Vector3’. Path ‘systemSimulationTransform_Pos.normalized’.
Here is the detailed error :
JsonSerializationException: Self referencing loop detected for property ‘normalized’ with type ‘UnityEngine.Vector3’. Path ‘systemSimulationTransform_Pos.normalized’.
Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.CheckForCircularReference (Newtonsoft.Json.JsonWriter writer, System.Object value, Newtonsoft.Json.Serialization.JsonProperty property, Newtonsoft.Json.Serialization.JsonContract contract, Newtonsoft.Json.Serialization.JsonContainerContract containerContract, Newtonsoft.Json.Serialization.JsonProperty containerProperty) (at :0)
Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.CalculatePropertyValues (Newtonsoft.Json.JsonWriter writer, System.Object value, Newtonsoft.Json.Serialization.JsonContainerContract contract, Newtonsoft.Json.Serialization.JsonProperty member, Newtonsoft.Json.Serialization.JsonProperty property, Newtonsoft.Json.Serialization.JsonContract& memberContract, System.Object& memberValue) (at :0)
Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeObject (Newtonsoft.Json.JsonWriter writer, System.Object value, Newtonsoft.Json.Serialization.JsonObjectContract contract, Newtonsoft.Json.Serialization.JsonProperty member, Newtonsoft.Json.Serialization.JsonContainerContract collectionContract, Newtonsoft.Json.Serialization.JsonProperty containerProperty) (at :0)
Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeValue (Newtonsoft.Json.JsonWriter writer, System.Object value, Newtonsoft.Json.Serialization.JsonContract valueContract, Newtonsoft.Json.Serialization.JsonProperty member, Newtonsoft.Json.Serialization.JsonContainerContract containerContract, Newtonsoft.Json.Serialization.JsonProperty containerProperty) (at :0)
Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeObject (Newtonsoft.Json.JsonWriter writer, System.Object value, Newtonsoft.Json.Serialization.JsonObjectContract contract, Newtonsoft.Json.Serialization.JsonProperty member, Newtonsoft.Json.Serialization.JsonContainerContract collectionContract, Newtonsoft.Json.Serialization.JsonProperty containerProperty) (at :0)
Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeValue (Newtonsoft.Json.JsonWriter writer, System.Object value, Newtonsoft.Json.Serialization.JsonContract valueContract, Newtonsoft.Json.Serialization.JsonProperty member, Newtonsoft.Json.Serialization.JsonContainerContract containerContract, Newtonsoft.Json.Serialization.JsonProperty containerProperty) (at :0)
Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeObject (Newtonsoft.Json.JsonWriter writer, System.Object value, Newtonsoft.Json.Serialization.JsonObjectContract contract, Newtonsoft.Json.Serialization.JsonProperty member, Newtonsoft.Json.Serialization.JsonContainerContract collectionContract, Newtonsoft.Json.Serialization.JsonProperty containerProperty) (at :0)
Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeValue (Newtonsoft.Json.JsonWriter writer, System.Object value, Newtonsoft.Json.Serialization.JsonContract valueContract, Newtonsoft.Json.Serialization.JsonProperty member, Newtonsoft.Json.Serialization.JsonContainerContract containerContract, Newtonsoft.Json.Serialization.JsonProperty containerProperty) (at :0)
Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.Serialize (Newtonsoft.Json.JsonWriter jsonWriter, System.Object value, System.Type objectType) (at :0)
Newtonsoft.Json.JsonSerializer.SerializeInternal (Newtonsoft.Json.JsonWriter jsonWriter, System.Object value, System.Type objectType) (at :0)
Newtonsoft.Json.JsonSerializer.Serialize (Newtonsoft.Json.JsonWriter jsonWriter, System.Object value, System.Type objectType) (at :0)
Newtonsoft.Json.JsonConvert.SerializeObjectInternal (System.Object value, System.Type type, Newtonsoft.Json.JsonSerializer jsonSerializer) (at :0)
Newtonsoft.Json.JsonConvert.SerializeObject (System.Object value, System.Type type, Newtonsoft.Json.Formatting formatting, Newtonsoft.Json.JsonSerializerSettings settings) (at :0)
Newtonsoft.Json.JsonConvert.SerializeObject (System.Object value, Newtonsoft.Json.Formatting formatting, Newtonsoft.Json.JsonSerializerSettings settings) (at :0)
Newtonsoft.Json.JsonConvert.SerializeObject (System.Object value, Newtonsoft.Json.Formatting formatting) (at :0)
ImportExportJSONManager._createSaveJSON () (at Assets/Scripts/Json/ImportExportJSONManager.cs:393)
ImportExportJSONManager.Save () (at Assets/Scripts/Json/ImportExportJSONManager.cs:121)
ImportExportJSONManagerEditor.OnInspectorGUI () (at Assets/Editor/ImportExportJSONManagerEditor.cs:42)
UnityEditor.UIElements.InspectorElement+<>c__DisplayClass59_0.b__0 () (at <5cd53c58cab44054a1ac592b0da25132>:0)
UnityEngine.GUIUtility:ProcessEvent(Int32, IntPtr, Boolean&)
Here is the code that cause the error:
return JsonConvert.SerializeObject(templateClass,Formatting.Indented);
I search on internet, and found that some options can be added to prevent this kind of error but I don’t know how to/where implement them.
Could you help me?
Thanks
NewtonSoft has a hard time serializing structs (Vector3 is defined as a struct). More specifically that struct has a property normalized that actually returns a Vector3 also, that Vector3 also has a normalized property and so on, so what happens is NewtonSoft is trying to serialize that new Vector3 everytime and you end up in an infinite loop.
If we had access to the Vector3 class code we could simply add the [JsonIgnore] attribute to the normalized property but we don’t.
My workaround for this was to create a custom class for this purpose:
[System.Serializable]
public class SerializableVector3{
public float x;
public float y;
public float z;
[JsonIgnore]
public Vector3 UnityVector{
return new Vector3(x, y, z);
public SerializableVector3(Vector3 v){
x = v.x;
y = v.y;
z = v.z;
public static List<SerializableVector3> GetSerializableList(List<Vector3> vList){
List<SerializableVector3> list = new List<SerializableVector3>(vList.Count);
for(int i = 0 ; i < vList.Count ; i++){
list.Add(new SerializableVector3(vList[i]));
return list;
public static List<Vector3> GetSerializableList(List<SerializableVector3> vList){
List<Vector3> list = new List<Vector3>(vList.Count);
for(int i = 0 ; i < vList.Count ; i++){
list.Add(vList[i].UnityVector);
return list;
Whenever you serialize a class make sure to convert all your Vector3 to SerializableVector3 and vice-versa when you deserialize. I use the ISerializable interface (System.Runtime.Serialization) for this purpose among other things.
Thanks you Ensiferum888 for your fast answer and for the explanations.
I tried to create the class by copying/pasting your code in a new SerializableVector3.cs script but I get some errors.
It seems that I should add some namespace like unityengine and System.Collections.Generic but it’s not enough.
Also the method UnityVector has no parenthesis after it’s declaration, is it normal?
"Whenever you serialize a class make sure to convert all your Vector3 to SerializableVector3 and vice-versa when you deserialize. I use the ISerializable interface (System.Runtime.Serialization) for this purpose among other things. "
=> Could you give me a small example please ? (I’m self taught coder)
Thanks for your help !
Hi Bennyman!
You are correct you do need the standard namespaces. I also made a typo for the UnityVector it’s not a method but a property, I updated the code with the proper get{} block.
I’m at work right now but I can absolutely give you some examples later today. I suggest you read up on ISerializable Interface (System.Runtime.Serialization) | Microsoft Docs
I’ll give you a more personalized explanation later.
Thanks again Ensiferum888.
It is working now 
I tried to understand the page your mentioned. Even if I understand the concept, I don’t understand the details, so I didn’t tried to implement it
Anyway, I kind of harcoded the 2 ways conversion in my script and it work. (I also created the same for Vector4).
Many thanks again !
You can use the ReferenceLoopHandling setting when serializing to address this. Worked perfectly for my needs.
Output in my case:
dhindman:
You can use the ReferenceLoopHandling setting when serializing to address this. Worked perfectly for my needs.
Output in my case:
Thanks man! it worked!
You could convert your Vector3 into a float array to serialize:
var newArr = new float[3]
yourVector3.x,
yourVector3.y,
your Vector3.z
Then, to Deserialize:
var jsonArr = your method of reading the serialized newArr, which returns a JArray Object.
var vectorArr = JsonConvert.DeserializeObject<float[ ]>(jsonArr.ToString());
var myVector = new Vector3(vectorArr[0], vectorArr[1], vectorArr[2]);
Not super fancy, but it works.
I have corrected the json.net for vectors. There are instructions on how to install and use.
That solves all the problems! 
GitHub - slavaWins/JsonUnityVectors: Fix json net for unity Vectors
dhindman:
You can use the ReferenceLoopHandling setting when serializing to address this. Worked perfectly for my needs.
Output in my case:
Just in case someone else is going through this thread looking to fix this, @dhindman answer is the right one, as it uses NewtonSoft’s implementation with no need to add any fix on your code or reinvent the wheel.
To make it easy here is the code you have to use when serializing your json to ignore self referencing loop:
string json = JsonConvert.SerializeObject(_yourObject, Formatting.Indented, new JsonSerializerSettings
ReferenceLoopHandling = ReferenceLoopHandling.Ignore
diegoop:
Just in case someone else is going through this thread looking to fix this, @dhindman answer is the right one, as it uses NewtonSoft’s implementation with no need to add any fix on your code or reinvent the wheel.
To make it easy here is the code you have to use when serializing your json to ignore self referencing loop:
string json = JsonConvert.SerializeObject(_yourObject, Formatting.Indented, new JsonSerializerSettings
ReferenceLoopHandling = ReferenceLoopHandling.Ignore
This crashes the unity editor.
It’s handy to learn writing custom Converters for Unity types in order to be decoupled from external dependencies, when the native solution does not work in certain versions or use cases within Unity.
A simple custom converter for the Color type would be:
public class ColorConverter : JsonConverter<Color>
public override void WriteJson(JsonWriter writer, Color value, JsonSerializer serializer)
JArray array = new(value.r, value.g, value.b, value.a);
array.WriteTo(writer);
public override Color ReadJson(JsonReader reader, Type objectType, Color existingValue, bool hasExistingValue, JsonSerializer serializer)
JArray array = JArray.Load(reader);
return new Color((float)array[0], (float)array[1], (float)array[2], (float)array[3]);
(You can infer how to convert basically any type easily from this)
And then add your custom converters to the global Json.NET settings once at Editor time (if needed) and once at runtime, so you will never have to deal with them ever again.
public static class JsonCustomSettings
public static void ConfigureJsonInternal()
JsonConvert.DefaultSettings = () =>
var settings = new JsonSerializerSettings();
settings.Converters.Add(new ColorConverter());
return settings;
// this must be inside an Editor/ folder
public static class EditorJsonSettings
[InitializeOnLoadMethod]
public static void ApplyCustomConverters()
JsonCustomSettings.ConfigureJsonInternal();
public static class RuntimeJsonSettings
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
public static void ApplyCustomConverters()
JsonCustomSettings.ConfigureJsonInternal();
(This solution here is a quick and dirty writedown, probably can be done cleaner)
A simple custom converter for the Color type would be:
public class ColorConverter : JsonConverter<Color>
public override void WriteJson(JsonWriter writer, Color value, JsonSerializer serializer)
JArray array = new(value.r, value.g, value.b, value.a);
array.WriteTo(writer);
public override Color ReadJson(JsonReader reader, Type objectType, Color existingValue, bool hasExistingValue, JsonSerializer serializer)
JArray array = JArray.Load(reader);
return new Color((float)array[0], (float)array[1], (float)array[2], (float)array[3]);
(You can infer how to convert basically any type easily from this)
Thanks for the reply, that helped me! But please note that the quoted solution expects Color to be an array, like below
"myColor": [
In my case, my project was parsing Vector2 correctly as an object without the need for custom parsers, so I already had a json formed with object, like below
"myVector2": {
"x": 0.5,
"y": 0.5
And suddently the parser started to throw the same self-recerence loop error (no idea why). I didn’t want to change my json file, so to do that you can use the code below
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
// Solutions to prevent serialization errors. Seen in https://discussions.unity.com/t/877513
// Newtonsoft struggles serializing structs like Vector3 because it has a property .normalized
// that references Vector3, and thus entering a self-reference loop throwing circular reference error.
// Add the class to BootstrapJsonParser
public class ColorConverter : JsonConverter<Color>
public override void WriteJson(JsonWriter writer, Color value, JsonSerializer serializer)
JObject obj = new JObject() { ["r"] = value.r, ["g"] = value.g, ["b"] = value.b, ["a"] = value.a };
obj.WriteTo(writer);
public override Color ReadJson(JsonReader reader, Type objectType, Color existingValue, bool hasExistingValue, JsonSerializer serializer)
JObject obj = JObject.Load(reader);
return new Color((float)obj.GetValue("r"), (float)obj.GetValue("g"), (float)obj.GetValue("b"), (float)obj.GetValue("a"));
public class Vector2Converter : JsonConverter<Vector2>
public override void WriteJson(JsonWriter writer, Vector2 value, JsonSerializer serializer)
JObject obj = new JObject() { ["x"] = value.x, ["y"] = value.y };
obj.WriteTo(writer);
public override Vector2 ReadJson(JsonReader reader, Type objectType, Vector2 existingValue, bool hasExistingValue, JsonSerializer serializer)
JObject obj = JObject.Load(reader);
return new Vector2((float)obj.GetValue("x"), (float)obj.GetValue("y"));
public class Vector3Converter : JsonConverter<Vector3>
public override void WriteJson(JsonWriter writer, Vector3 value, JsonSerializer serializer)
JObject obj = new JObject() { ["x"] = value.x, ["y"] = value.y, ["z"] = value.z };
obj.WriteTo(writer);
public override Vector3 ReadJson(JsonReader reader, Type objectType, Vector3 existingValue, bool hasExistingValue, JsonSerializer serializer)
JObject obj = JObject.Load(reader);
return new Vector3((float)obj.GetValue("x"), (float)obj.GetValue("y"), (float)obj.GetValue("z"));
public class Vector4Converter : JsonConverter<Vector4>
public override void WriteJson(JsonWriter writer, Vector4 value, JsonSerializer serializer)
JObject obj = new JObject() { ["x"] = value.x, ["y"] = value.y, ["z"] = value.z, ["w"] = value.w };
obj.WriteTo(writer);
public override Vector4 ReadJson(JsonReader reader, Type objectType, Vector4 existingValue, bool hasExistingValue, JsonSerializer serializer)
JObject obj = JObject.Load(reader);
return new Vector4((float)obj.GetValue("x"), (float)obj.GetValue("y"), (float)obj.GetValue("z"), (float)obj.GetValue("w"));
And if using this code, don’t forget to change the JsonCustomSettings.
public static class JsonCustomSettings
public static void ConfigureJsonInternal()
JsonConvert.DefaultSettings = () =>
var settings = new JsonSerializerSettings();
settings.Converters.Add(new ColorConverter());
settings.Converters.Add(new Vector2Converter());
settings.Converters.Add(new Vector3Converter());
settings.Converters.Add(new Vector4Converter());
return settings;
// this must be inside an Editor/ folder
public static class EditorJsonSettings
[InitializeOnLoadMethod]
public static void ApplyCustomConverters()
JsonCustomSettings.ConfigureJsonInternal();
public static class RuntimeJsonSettings
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
public static void ApplyCustomConverters()
JsonCustomSettings.ConfigureJsonInternal();
This crashes the unity editor.
It’s handy to learn writing custom Converters for Unity types in order to be decoupled from external dependencies, when the native solution does not work in certain versions or use cases within Unity.
A simple custom converter for the Color type would be:
public class ColorConverter : JsonConverter<Color>
public override void WriteJson(JsonWriter writer, Color value, JsonSerializer serializer)
JArray array = new(value.r, value.g, value.b, value.a);
array.WriteTo(writer);
public override Color ReadJson(JsonReader reader, Type objectType, Color existingValue, bool hasExistingValue, JsonSerializer serializer)
JArray array = JArray.Load(reader);
return new Color((float)array[0], (float)array[1], (float)array[2], (float)array[3]);
(You can infer how to convert basically any type easily from this)
And then add your custom converters to the global Json.NET settings once at Editor time (if needed) and once at runtime, so you will never have to deal with them ever again.
public static class JsonCustomSettings
public static void ConfigureJsonInternal()
JsonConvert.DefaultSettings = () =>
var settings = new JsonSerializerSettings();
settings.Converters.Add(new ColorConverter());
return settings;
// this must be inside an Editor/ folder
public static class EditorJsonSettings
[InitializeOnLoadMethod]
public static void ApplyCustomConverters()
JsonCustomSettings.ConfigureJsonInternal();
public static class RuntimeJsonSettings
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
public static void ApplyCustomConverters()
JsonCustomSettings.ConfigureJsonInternal();
(This solution here is a quick and dirty writedown, probably can be done cleaner)
You answer is the best! Thank you!
pmelo:
And suddently the parser started to throw the same self-recerence loop error (no idea why). I didn’t want to change my json file, so to do that you can use the code below
Thank you, it helped me. This code can become a little more readable.
// Solutions to prevent serialization errors. Seen in https://discussions.unity.com/t/877513
// Newtonsoft struggles serializing structs like Vector3 because it has a property .normalized
// that references Vector3, and thus entering a self-reference loop throwing circular reference error.
using Newtonsoft.Json.Linq;
using Newtonsoft.Json;
using UnityEngine;
using System;
public sealed class NewtonsoftColorConverter : JsonConverter<Color>
public override void WriteJson(JsonWriter writer, Color value, JsonSerializer serializer)
JObject obj = new JObject
new JProperty("r", value.r),
new JProperty("g", value.g),
new JProperty("b", value.b),
new JProperty("a", value.a)
obj.WriteTo(writer);
public override Color ReadJson(JsonReader reader, Type objectType, Color existingValue, bool hasExistingValue, JsonSerializer serializer)
JObject obj = JObject.Load(reader);
return new Color
obj.Value<float>("r"),
obj.Value<float>("g"),
obj.Value<float>("b"),
obj.Value<float>("a")
public sealed class NewtonsoftQuaternionConverter : JsonConverter<Quaternion>
public override void WriteJson(JsonWriter writer, Quaternion value, JsonSerializer serializer)
JObject obj = new JObject
new JProperty("x", value.x),
new JProperty("y", value.y),
new JProperty("z", value.z),
new JProperty("w", value.w)
obj.WriteTo(writer);
public override Quaternion ReadJson(JsonReader reader, Type objectType, Quaternion existingValue, bool hasExistingValue, JsonSerializer serializer)
JObject obj = JObject.Load(reader);
return new Quaternion
obj.Value<float>("x"),
obj.Value<float>("y"),
obj.Value<float>("z"),
obj.Value<float>("w")
public sealed class NewtonsoftVector2Converter : JsonConverter<Vector2>
public override void WriteJson(JsonWriter writer, Vector2 value, JsonSerializer serializer)
JObject obj = new JObject
new JProperty("x", value.x),
new JProperty("y", value.y)
obj.WriteTo(writer);
public override Vector2 ReadJson(JsonReader reader, Type objectType, Vector2 existingValue, bool hasExistingValue, JsonSerializer serializer)
JObject obj = JObject.Load(reader);
return new Vector2
obj.Value<float>("x"),
obj.Value<float>("y")
public sealed class NewtonsoftVector2IntConverter : JsonConverter<Vector2Int>
public override void WriteJson(JsonWriter writer, Vector2Int value, JsonSerializer serializer)
JObject obj = new JObject
new JProperty("x", value.x),
new JProperty("y", value.y)
obj.WriteTo(writer);
public override Vector2Int ReadJson(JsonReader reader, Type objectType, Vector2Int existingValue, bool hasExistingValue, JsonSerializer serializer)
JObject obj = JObject.Load(reader);
return new Vector2Int
obj.Value<int>("x"),
obj.Value<int>("y")
public sealed class NewtonsoftVector3Converter : JsonConverter<Vector3>
public override void WriteJson(JsonWriter writer, Vector3 value, JsonSerializer serializer)
JObject obj = new JObject
new JProperty("x", value.x),
new JProperty("y", value.y),
new JProperty("z", value.z)
obj.WriteTo(writer);
public override Vector3 ReadJson(JsonReader reader, Type objectType, Vector3 existingValue, bool hasExistingValue, JsonSerializer serializer)
JObject obj = JObject.Load(reader);
return new Vector3
obj.Value<float>("x"),
obj.Value<float>("y"),
obj.Value<float>("z")
public sealed class NewtonsoftVector3IntConverter : JsonConverter<Vector3Int>
public override void WriteJson(JsonWriter writer, Vector3Int value, JsonSerializer serializer)
JObject obj = new JObject
new JProperty("x", value.x),
new JProperty("y", value.y),
new JProperty("z", value.z)
obj.WriteTo(writer);
public override Vector3Int ReadJson(JsonReader reader, Type objectType, Vector3Int existingValue, bool hasExistingValue, JsonSerializer serializer)
JObject obj = JObject.Load(reader);
return new Vector3Int
obj.Value<int>("x"),
obj.Value<int>("y"),
obj.Value<int>("z")
public sealed class NewtonsoftVector4Converter : JsonConverter<Vector4>
public override void WriteJson(JsonWriter writer, Vector4 value, JsonSerializer serializer)
JObject obj = new JObject
new JProperty("x", value.x),
new JProperty("y", value.y),
new JProperty("z", value.z),
new JProperty("w", value.w)
obj.WriteTo(writer);
public override Vector4 ReadJson(JsonReader reader, Type objectType, Vector4 existingValue, bool hasExistingValue, JsonSerializer serializer)
JObject obj = JObject.Load(reader);
return new Vector4
obj.Value<float>("x"),
obj.Value<float>("y"),
obj.Value<float>("z"),
obj.Value<float>("w")
You may use "return JObject.Load(reader).Value();" in ReadJson() but i think it will work only for array type.