Skip to content

Instantly share code, notes, and snippets.

@stakira
Created March 1, 2018 19:13
Show Gist options
  • Save stakira/0bced474459ecc2c3a8670a1e31d5f14 to your computer and use it in GitHub Desktop.
Save stakira/0bced474459ecc2c3a8670a1e31d5f14 to your computer and use it in GitHub Desktop.
Unity settings loader for build pipeline
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using UnityEditor;
using UnityEngine;
namespace AnySettings
{
[InitializeOnLoad]
public static class AnySettings
{
private static void Serialize(Type klass, Dictionary<string, object> dict)
{
var subdict = new Dictionary<string, object>();
var flags = BindingFlags.Public | BindingFlags.Static;
var props = klass.GetProperties(flags);
foreach (var prop in props) {
if (!prop.CanRead || !prop.CanWrite) {
// ignored
} else if (prop.PropertyType.IsPrimitive || prop.PropertyType == typeof(string)) {
subdict[prop.Name] = prop.GetValue(null, null);
} else if (prop.PropertyType.IsEnum) {
subdict[prop.Name] = Enum.GetName(prop.PropertyType, prop.GetValue(null, null));
}
}
dict[klass.FullName] = subdict;
}
private static void Deserialize(string typeFullName, Dictionary<string, object> dict)
{
Type klass = null;
foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies()) {
klass = assembly.GetType(typeFullName);
if (klass != null) {
break;
}
}
if (klass == null) {
return;
}
var changes = new List<string>();
var subdict = dict[typeFullName] as Dictionary<string, object>;
foreach (var key in subdict.Keys) {
var v = subdict[key];
var flags = BindingFlags.Public | BindingFlags.Static;
var prop = klass.GetProperty(key, flags);
if (prop == null) {
Debug.LogErrorFormat("Property {0} doesn't exist in {1}", key, klass.FullName);
continue;
}
if (prop.PropertyType.IsPrimitive) {
var oldValue = prop.GetValue(null, null);
if (!oldValue.Equals(v)) {
changes.Add(string.Format("{0}\t\t{1} -> {2}", prop.Name, oldValue, v));
prop.SetValue(null, v, null);
}
}
if (prop.PropertyType == typeof(string)) {
var oldValue = prop.GetValue(null, null);
var a = string.IsNullOrEmpty((string)oldValue);
var b = string.IsNullOrEmpty((string)v);
if (a != b || !a && !b && !oldValue.Equals(v)) {
changes.Add(string.Format("{0}\t\t{1} -> {2}", prop.Name, oldValue, v));
prop.SetValue(null, v, null);
}
} else if (prop.PropertyType.IsEnum) {
var oldValue = prop.GetValue(null, null);
if (Enum.GetName(prop.PropertyType, oldValue) != (string)v) {
var newValue = Enum.Parse(prop.PropertyType, (string)v);
changes.Add(string.Format("{0}\t\t{1} -> {2}", prop.Name, oldValue, newValue));
prop.SetValue(null, newValue, null);
}
}
}
if (changes.Count > 0) {
Debug.LogFormat("Setting {0}:\n{1}", typeFullName, string.Join("\n", changes.ToArray()));
}
}
#region methods
public static string DumpSettings()
{
Type[] settingTypes = {
typeof(PlayerSettings),
typeof(PlayerSettings.Android),
typeof(PlayerSettings.iOS),
typeof(EditorUserBuildSettings),
// typeof(YourProjectBuildSetting), // You could create (wrapper) properties for arbitrary things
};
var dict = new Dictionary<string, object>();
foreach (var type in settingTypes) {
Serialize(type, dict);
}
return Newtonsoft.Json.JsonConvert.SerializeObject(dict, Newtonsoft.Json.Formatting.Indented);
}
public static void LoadSettings(string json)
{
var dict = AmplitudeNS.MiniJSON.Json.Deserialize(json) as Dictionary<string, object>;
foreach (var key in dict.Keys) {
Deserialize(key, dict);
}
}
[MenuItem("Build/View All Current Settings")]
public static void ViewAll()
{
Debug.Log(DumpSettings());
}
[MenuItem("Build/Load Settings From File")]
public static void LoadFromFile()
{
string path = EditorUtility.OpenFilePanel("Load Settings", "Settings", null);
if (!string.IsNullOrEmpty(path) && File.Exists(path)) {
LoadSettings(File.ReadAllText(path));
}
AssetDatabase.SaveAssets();
}
#endregion
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment