Skip to content

Instantly share code, notes, and snippets.

@zplume
Last active July 19, 2023 04:30
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zplume/0ec6b4c2df30e11e223c9e09f931f49b to your computer and use it in GitHub Desktop.
Save zplume/0ec6b4c2df30e11e223c9e09f931f49b to your computer and use it in GitHub Desktop.
Example of polymorphic serialisation with JsonUtility
using UnityEngine;
using System;
[Serializable]
public class Collectable : PolymorphicObject
{
public string Name;
}
using UnityEngine;
public class Data : ScriptableObject
{
public virtual void Save(string key)
{
var data = JsonUtility.ToJson(this);
PlayerPrefs.SetString(key, data);
PlayerPrefs.Save();
}
public virtual void Load(string key)
{
var data = PlayerPrefs.GetString(key);
JsonUtility.FromJsonOverwrite(data, this);
}
}
using System;
[Serializable]
public class Engine : Module
{
public float Acceleration;
public float MaxSpeed;
}
using System;
[Serializable]
public class FuelTank : Module
{
public float Capacity;
}
public class Module : Collectable
{
}
using System.Collections.Generic;
using UnityEngine;
using System;
using System.Linq;
[CreateAssetMenuAttribute(menuName="Data/Player")]
public class Player : Data
{
private const string SaveKey = "Player";
[NonSerialized]
public List<Collectable> cargo;
[SerializeField]
private List<string> cargoSerialised;
public void Save()
{
cargoSerialised = cargo.Select(c => JsonUtility.ToJson(c)).ToList();
base.Save(SaveKey);
}
public void Load()
{
base.Load(SaveKey);
cargo = cargoSerialised.Select(c => Collectable.FromJson<Collectable>(c)).ToList();
sectorUpdate.OnLoad();
}
[ContextMenu("Clear data")]
private void ClearData()
{
PlayerPrefs.DeleteKey(SaveKey);
cargo.Clear();
}
}
using UnityEngine;
using System;
/// <summary>
/// Inherit from this class to allow polymorphic (de)serialisation via JsonUtility.
/// Inheriting classes should be marked as [System.Serializable]
/// </summary>
public abstract class PolymorphicObject
{
[HideInInspector]
public string AssemblyQualifiedName; // for deserialising as the correct type
public string TypeName; // for displaying the friendly type name in the inspector
public static T FromJson<T>(string json) where T : PolymorphicObject
{
// deserialise first as PolymorphicObject to get the instance Type
var type = Type.GetType(JsonUtility.FromJson<T>(json).AssemblyQualifiedName);
// deserialise as the correct type
return (T)JsonUtility.FromJson(json, type);
}
public PolymorphicObject()
{
// AssemblyQualifiedName is public and will be serialised
// when using JsonUtility.ToJson
var type = this.GetType();
AssemblyQualifiedName = type.AssemblyQualifiedName;
TypeName = type.Name.Split(',')[0];
}
}
using System;
[Serializable]
public class Shield : Module
{
public float Hitpoints;
public float RegenAmount;
public float RegenSpeed;
}
using System;
[Serializable]
public class Weapon : Module
{
public float RateOfFire;
public float Damage;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment