Skip to content

Instantly share code, notes, and snippets.

@sebtoun
Last active February 27, 2024 17:25
Show Gist options
  • Star 15 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • 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();
}
}
@yadavamarjeet
Copy link

yadavamarjeet commented Jul 5, 2021

Hey can you give me any example how can i use it because i used it but in inspector the "load file" and "save file" button not showing please help i want to serialize scriptableObjecs. Thanks :)

public class Items : JsonSerialisableScriptableObject<Items>
{
    public List<int> prices = new List<int>();
    public List<Sprite> ImagesWithStars = new List<Sprite>();
    public List<Sprite> Building = new List<Sprite>();
    public List<Sprite> Building_damaged = new List<Sprite>();
}

@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