/*WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW*\ ( ( ) ) |/ \| ) ) _((_ || (c) Wanzyee Studio < wanzyeestudio.blogspot.com > || ( ( |_ _ |=n |\ /| _____)) | ! ] U \.ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ./ (_(__(S) |___*/ using UnityEngine; using System; using System.Collections.Generic; using System.Linq; using Newtonsoft.Json; using Newtonsoft.Json.Converters; namespace WanzyeeStudio.Json{ /// /// Integrate custom Newtonsoft.Json.JsonConverter to use /// Json.NET in Unity. /// /// /// /// To use Json.NET, please set Unity "PlayerSettings/Api Compatibility Lavel" to .NET 2.0. /// Then download from its website and import the .NET 2.0 dll. /// Json.NET doesn't support serializing some types originally, e.g., UnityEngine.Vector3. /// This has the defaultSettings includes necessary custom converters by default for Unity using it. /// And assign to Newtonsoft.Json.JsonConvert.DefaultSettings when initializing if the original null. /// /// /// /// Now we can use Json.NET just like before: /// /// /// /// Debug.Log(JsonConvert.SerializeObject(Vector3.up)); /// var vec = JsonConvert.DeserializeObject("{'x':1.0,'y':0.0}"); /// /// /// /// User can directly modify defaultSettings for customization, and override it: /// /// /// /// JsonConvert.DefaultSettings = () => new JsonSerializerSettings(){ /// Converters = JsonNetUtility.defaultSettings.Converters, /// DefaultValueHandling = DefaultValueHandling.Populate /// }; /// /// public static class JsonNetUtility{ #region Fields /// /// The default Newtonsoft.Json.JsonSerializerSettings. /// /// /// /// All its properties stay default, but the Converters includes below: /// 1. Any custom Newtonsoft.Json.JsonConverter has constructor without parameters. /// 2. Any Newtonsoft.Json.JsonConverter from WanzyeeStudio.Json. /// 3. Newtonsoft.Json.Converters.StringEnumConverter. /// 4. Newtonsoft.Json.Converters.VersionConverter. /// /// public static JsonSerializerSettings defaultSettings = new JsonSerializerSettings(){ Converters = CreateConverters() }; #endregion #region Methods /// /// Initialize when start up, set Newtonsoft.Json.JsonConvert.DefaultSettings if not yet. /// [RuntimeInitializeOnLoadMethod] private static void Initialize(){ if(null == JsonConvert.DefaultSettings) JsonConvert.DefaultSettings = () => defaultSettings; } /// /// Create the converter instances. /// /// The converters. private static List CreateConverters(){ var _customs = FindConverterTypes().Select((type) => CreateConverter(type)); var _builtins = new JsonConverter[]{new StringEnumConverter(), new VersionConverter()}; return _customs.Concat(_builtins).Where((converter) => null != converter).ToList(); } /// /// Try to create the converter of specified type. /// /// The converter. /// Type. private static JsonConverter CreateConverter(Type type){ try{ return Activator.CreateInstance(type) as JsonConverter; } catch(Exception exception){ Debug.LogErrorFormat("Can't create JsonConverter {0}:\n{1}", type, exception); } return null; } /// /// Find all the valid converter types. /// /// The types. private static Type[] FindConverterTypes(){ return AppDomain.CurrentDomain.GetAssemblies( ).SelectMany((dll) => dll.GetTypes() ).Where((type) => typeof(JsonConverter).IsAssignableFrom(type) ).Where((type) => (!type.IsAbstract && !type.IsGenericTypeDefinition) ).Where((type) => null != type.GetConstructor(new Type[0]) ).Where((type) => !(null != type.Namespace && type.Namespace.StartsWith("Newtonsoft.Json")) ).OrderBy((type) => null != type.Namespace && type.Namespace.StartsWith("WanzyeeStudio") ).ToArray(); } #endregion #if UNITY_EDITOR /// /// Initialize in edit mode. /// /* * http://stackoverflow.com/q/44655667 * There's a bug of RuntimeInitializeOnLoadMethodAttribute issued above. * Here directly split into two initialize methods to avoid that, and make the code cleaner. */ [UnityEditor.InitializeOnLoadMethod] private static void InitializeEditor(){ Initialize(); } #endif } }