Hi,
I’m trying to reconcile the behavior I’m observing in Unity 5.5 with the API / Manual documentation. I’ve searched high-and-low, and while I’ve found a lot about serializing inherited classes, and understand the well documented and answered limitations, I can’t find anything that addresses this issue.
According to JSON Serialization => Supported Types, “The object you pass in is fed to the standard Unity serializer for processing[…]”, and according to Script Serialization =>Fieldtypes that can be serialized, the standard serializer supports References to GameObjects that derive from UnityEngine.Object, which based on inheritance should include MonoBehaviour.
If I have a class that inherits from a MonoBehaviour, it will serialize properly when passed directly into the serializer, but if that same object is a field of another class, it will only serialize the Instance ID. See a small example of the behavior below. Before I start moving down one of the many alternate paths (e.g., callbacks, data containers, alternate serialization system), am I missing something simple? Misreading the documentation?
A Player Class (Attached to GameObject):
using UnityEngine;
public class Player : MonoBehaviour {
public float health;
public string playerName;
}
A Player Data Class with identical fields (Want to Avoid These):
[System.Serializable]
public class PlayerData {
public float health;
public string playerName;
}
The Game Data Class with a MonoBehaviour field:
[System.Serializable]
public class GameData {
public Player player; //Inherits from MonoBehaviour
public PlayerData playerData;
}
A Data Controller to test the Serialization:
using UnityEngine;
public class DataController : MonoBehaviour {
void Start () {
GameData gameData = new GameData();
Player player = GameObject.Find("Player").GetComponent<Player>();
PlayerData playerData = new PlayerData();
player.health = 100f;
player.playerName = "Player Name";
gameData.player = player;
playerData.health = 50f;
playerData.playerName = "PlayerData Name";
gameData.playerData = playerData;
string gameDataJson = JsonUtility.ToJson(gameData);
Debug.Log(JsonUtility.ToJson(gameData));
//Logs: {"player":{"instanceID":-3768},"playerData":{"health":50.0,"playerName":"PlayerData Name"}}
// MonoBehavior not serialized as field of object.
Debug.Log(JsonUtility.ToJson(player));
//Logs: {"health":100.0,"playerName":"Player Name"}
//MonoBehavior can be serialized directly
gameData.player.playerName = "Updated Player Name";
GameData restoredGameData = JsonUtility.FromJson<GameData>(gameDataJson);
Debug.Log(restoredGameData.player.playerName);
//Logs: "Updated Player Name"
//Deserialization returns the instance (as expected from instance ID), not the original values
}
}
Thanks for your help!