JsonUtility not serializing a field with the same type as the serialized object

The following class “ControllerAction” isn’t serialized quite right by JsonUtility. Any thoughts for what might be going wrong?

When another class that has a field of type “ControllerAction” is serialized, then that field shows up as part of the serialization. However, the “Next” field never shows up in any serializations of “ControllerAction”.

I’m thinking that the issue might be because the “Next” field of “ControllerAction” is, itself, a “ControllerAction”. However, I haven’t been able to find reference to JsonUtility being unable to serialize a field with the same type as it’s owner.

FYI: the “Next” parameter is used for chaining actions. It is never going to be infinitely looped by the larger application. (Edit: added Emphasis)

[Serializable]
public class ControllerAction
{
  public enum ActionType
  {
    Undo,
    Redo
  }
  public ActionType Type;
  public int Parameter;
  public ControllerAction Next;
}

EDIT: The presented class is a stripped down version of the full class in the application. Changes include more values in the “ActionType” enum and a public method.

_
TL;DR: JsonUtility does not support null
_

Because serializing this self-referencing object class by value would create a sub-optimal result in shape of an ininitely-long file and crashed your system.

{
    "Type" : "Undo",
	"Parameter" : "0",
	"Next" : {
		"Type" : "Undo",
		"Parameter" : "0",
		"Next" : {
			"Type" : "Undo",
			"Parameter" : "0",
			"Next" : ... ad infinitum
        }
    }
}

_

Proof

Look at what happens when your walkaround this safety feature:

using UnityEngine;

[ExecuteAlways]
public class SelfReferencingObjectsToJson : MonoBehaviour
{
    [SerializeField] ControllerAction _object = default(ControllerAction);
    [SerializeField] string _objectJson;
    void OnEnable () => OnValidate();
    void OnValidate () => _objectJson = JsonUtility.ToJson(_object);
}

[System.Serializable]
public class ControllerActionBase
{
    public enum ActionType { Undo , Redo }
    public ActionType Type;
    public int Parameter;
    public ControllerAction Next;
}

[System.Serializable]
public class ControllerAction : ControllerActionBase {}

problem with self referencing object json

Fortunately, there is yet another safety feature in place, preventing a disaster in such cases:

(Console log):

Serialization depth limit 10 exceeded at ‘ControllerActionBase.Next’. There may be an object composition cycle in one or more of your serialized classes.

_

Fix

What you might want to do instead is to create a simple local reference system yourself here, for example, like this:

using UnityEngine;

[ExecuteAlways]
public class SerializeLocalReferencesJson : MonoBehaviour
{
    [SerializeField] ControllerActions _objects;
    [SerializeField] string _objectJson;
    void OnEnable () => OnValidate();
    void OnValidate () => _objectJson = JsonUtility.ToJson(_objects);
}

[System.Serializable]
public class ControllerActions
{
    public ControllerAction[] Instances;
}

[System.Serializable]
public class ControllerAction
{
    public enum ActionType { Undo , Redo }
    public ActionType Type;
    public int Parameter;
    public int Next;
}

where references are resolved by index.
self referencing object json serialization fix