Skip to content

Instantly share code, notes, and snippets.

@sebtoun
Last active February 27, 2024 17:25
Show Gist options
  • Save sebtoun/205d455bbb9fedc5d6b976c4e588c03f to your computer and use it in GitHub Desktop.
Save sebtoun/205d455bbb9fedc5d6b976c4e588c03f to your computer and use it in GitHub Desktop.
Unity's ScriptableObjects that easily serialize to JSON
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using UnityEngine;
public class JsonSerialisableScriptableObject<T> : ScriptableObject where T : JsonSerialisableScriptableObject<T>
{
public void LoadJsonFromFile( string filename )
{
Debug.Log( string.Format( "[{0}] Read file {1}", typeof( T ).Name, filename ) );
LoadJsonFromText( File.ReadAllText( filename ) );
}
public void LoadJsonFromText( string json )
{
var settings = new JsonSerializerSettings()
{
ObjectCreationHandling = ObjectCreationHandling.Replace
};
JsonConvert.PopulateObject( json, this, settings );
OnPostJsonDeserialization();
}
public string DumpJson()
{
var settings = new JsonSerializerSettings()
{
ContractResolver = new DerivedTypeOnlyContractResolver<T>(),
Formatting = Formatting.Indented
};
return JsonConvert.SerializeObject( this, settings );
}
public void DumpJsonToFile( string filename )
{
Debug.Log( string.Format( "[{0}] Write file {1}", typeof( T ).Name, filename ) );
File.WriteAllText( filename, DumpJson() );
}
protected virtual void OnPostJsonDeserialization()
{
}
private class DerivedTypeOnlyContractResolver<T> : DefaultContractResolver
{
protected override IList<JsonProperty> CreateProperties( Type type, MemberSerialization memberSerialization )
{
var properties = base.CreateProperties( type, memberSerialization );
if ( !typeof( T ).IsAssignableFrom( type ) )
{
return properties;
}
else
{
return properties.Where( property => property.DeclaringType == typeof( T ) ).ToList();
}
}
}
}
using System.IO;
using UnityEditor;
using UnityEngine;
public class JsonSerialisableScriptableObjectEditor<T> : Editor where T : JsonSerialisableScriptableObject<T>
{
public override void OnInspectorGUI()
{
var scriptableObject = (T) target;
using ( new EditorGUILayout.HorizontalScope() )
{
if ( GUILayout.Button( "Load File" ) )
{
var filename = EditorUtility.OpenFilePanel( "Load Json File", Application.dataPath, "json" );
if ( !string.IsNullOrEmpty( filename ) && File.Exists( filename ) )
{
scriptableObject.LoadJsonFromFile( filename );
}
}
if ( GUILayout.Button( "Save File" ) )
{
var filename = EditorUtility.SaveFilePanel( "Save Json File", Application.dataPath,
scriptableObject.name + ".json", "json" );
if ( !string.IsNullOrEmpty( filename ) )
{
scriptableObject.DumpJsonToFile( filename );
}
}
}
base.OnInspectorGUI();
}
}
@HoshinoArika
Copy link

Hi, there is a typo in class name “JsonSeriali [s] ableScriptableObject”

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment