#define UNITY_5_PLUS #if UNITY_4_5 || UNITY_4_6 || UNITY_4_7 || UNITY_4_8 || UNITY_4_9 #undef UNITY_5_PLUS #endif using System; using System.Runtime.InteropServices; //using UnityEditor; using System.Reflection; using UnityEngine; using System.Collections.Generic; using Newtonsoft.Json; namespace UltraControls { public class JsonVector2 { public CtrlType type; public float x; public float y; public JsonVector2(Vector2 vec2) { x = vec2.x; y = vec2.y; type = CtrlType.Vec2F; } public Vector2 To() { return new Vector2(x, y); } } public class JsonVector3 { public CtrlType type; public float x; public float y; public float z; public JsonVector3(Vector3 vec3) { x = vec3.x; y = vec3.y; z = vec3.z; type = CtrlType.Vec3F; } public Vector3 To() { return new Vector3(x, y, z); } } public class JsonVector4 { public CtrlType type; public float x; public float y; public float z; public float w; public JsonVector4(Vector4 vec4) { x = vec4.x; y = vec4.y; z = vec4.z; w = vec4.w; type = CtrlType.Vec4F; } public Vector4 To() { return new Vector4(x, y, z, w); } } public class JsonColor { public CtrlType type; public float r; public float g; public float b; public float a; public JsonColor(Color color) { r = color.r; g = color.g; b = color.b; a = color.a; type = CtrlType.ColorF; } public Color To() { return new Color(r, g, b, a); } } public class JsonColor32 { public CtrlType type; public byte r; public byte g; public byte b; public byte a; public JsonColor32(Color32 color) { r = color.r; g = color.g; b = color.b; a = color.a; type = CtrlType.Color; } public Color32 To() { return new Color32(r, g, b, a); } } public sealed class Utils { public static string ToJson(Control[] controls) { if (controls == null) { return ""; } var values = new Dictionary(); foreach (Control ctrl in controls) { switch (ctrl.ctrlType) { case CtrlType.Bool: values[ctrl.name] = ctrl.valBool; break; case CtrlType.Text: values[ctrl.name] = ctrl.text; break; case CtrlType.Float: values[ctrl.name] = ctrl.valFloat; break; case CtrlType.Int: values[ctrl.name] = ctrl.valInt; break; case CtrlType.Vec2F: values[ctrl.name] = new JsonVector2(ctrl.valVector2); break; case CtrlType.Vec3F: values[ctrl.name] = new JsonVector3(ctrl.valVector3); break; case CtrlType.Vec4F: values[ctrl.name] = new JsonVector4(ctrl.valVector4); break; case CtrlType.ColorF: values[ctrl.name] = new JsonColor(ctrl.valColor); break; case CtrlType.Color: values[ctrl.name] = new JsonColor32(ctrl.valColor32); break; default: break; } } // save preset setting return JsonConvert.SerializeObject(values, Formatting.Indented); } public static void FromJson(string in_str_json, Control[] out_controls) { if (out_controls == null) { return; } JsonSerializerSettings setting = new JsonSerializerSettings(); setting.MissingMemberHandling = MissingMemberHandling.Ignore; setting.DefaultValueHandling = DefaultValueHandling.Include; setting.NullValueHandling = NullValueHandling.Ignore; var res = JsonConvert.DeserializeObject< Dictionary >(in_str_json, setting); foreach (Control ctrl in out_controls) { object obj; if (res.TryGetValue(ctrl.name, out obj)) { Type type = obj.GetType(); if (type == typeof(string) && ctrl.IsString()) { ctrl.text = (string)obj; } else if (ctrl.IsValue()) { if (type == typeof(bool)) { ctrl.valBool = (bool)obj; } else if (type == typeof(Double)) { ctrl.valFloat = Convert.ToSingle((Double)obj); } else if (type == typeof(float)) { ctrl.valFloat = (float)obj; } else if (type == typeof(Int64)) { ctrl.valInt = Convert.ToInt32((Int64)obj); } else if (type == typeof(int)) { ctrl.valInt = (int)obj; } else if (type == typeof(Newtonsoft.Json.Linq.JObject)) { Newtonsoft.Json.Linq.JObject jobj = (Newtonsoft.Json.Linq.JObject)obj; Newtonsoft.Json.Linq.JToken token = jobj.GetValue("type"); if (token == null) { continue; } CtrlType jobj_type = (CtrlType)(int)token; if (jobj_type != ctrl.ctrlType) { continue; } switch (ctrl.ctrlType) { case CtrlType.Vec2F: { JsonVector2 json_vec2 = JsonConvert.DeserializeObject(obj.ToString()); if (json_vec2 == null) { continue; } ctrl.valVector2 = json_vec2.To(); } break; case CtrlType.Vec3F: { JsonVector3 json_vec3 = JsonConvert.DeserializeObject(obj.ToString()); if (json_vec3 == null) { continue; } ctrl.valVector3 = json_vec3.To(); } break; case CtrlType.Vec4F: { JsonVector4 json_vec4 = JsonConvert.DeserializeObject(obj.ToString()); if (json_vec4 == null) { continue; } ctrl.valVector2 = json_vec4.To(); } break; case CtrlType.ColorF: { JsonColor json_color = JsonConvert.DeserializeObject(obj.ToString()); if (json_color == null) { continue; } ctrl.valColor = json_color.To(); } break; case CtrlType.Color: { JsonColor32 json_color32 = JsonConvert.DeserializeObject(obj.ToString()); if (json_color32 == null) { continue; } ctrl.valColor32 = json_color32.To(); } break; default: continue; } } } } } } public static string GetRelativeDefaultDir() { string dir = "settings-ultracontrols/"; System.IO.DirectoryInfo root_dir = System.IO.Directory.GetParent(Application.dataPath); string path = System.IO.Path.Combine(root_dir.FullName, dir); System.IO.DirectoryInfo default_dir = new System.IO.DirectoryInfo(path); if (!default_dir.Exists) { default_dir.Create(); } return dir; } public static T BytesToStructure(byte[] bytes) where T : class { GCHandle handle = GCHandle.Alloc(bytes, System.Runtime.InteropServices.GCHandleType.Pinned); T obj = (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(T)); handle.Free(); return obj; } public static void StructureToBytes(T obj, byte[] bytes) where T : class { //GCHandle handle = GCHandle.Alloc(bytes, System.Runtime.InteropServices.GCHandleType.Pinned); int size = Marshal.SizeOf(obj); IntPtr ptr = Marshal.AllocHGlobal(size); Marshal.StructureToPtr(obj, ptr, false); Marshal.Copy(ptr, bytes, 0, size); Marshal.FreeHGlobal(ptr); } public static RawCtrl[] AllocAryRawCtrl(uint num) { RawCtrl[] ary = new RawCtrl[num]; for (uint i = 0; i < num; ++i) { ary[i] = new RawCtrl(); ary[i].name = ""; ary[i].data = new byte[236]; } return ary; } public static CtrlValues AllocCtrlVaules() { CtrlValues values = new CtrlValues(); values.val = new float[16]; values.min = new float[16]; values.max = new float[16]; return values; } public static CtrlType GetCtrlType(Type type) { if (type == typeof(string)) { return CtrlType.Text; } else if (type == typeof(bool)) { return CtrlType.Bool; } else if (type == typeof(float)) { return CtrlType.Float; } else if (type == typeof(int)) { return CtrlType.Int; } else if (type == typeof(Vector2)) { return CtrlType.Vec2F; } else if (type == typeof(Vector3)) { return CtrlType.Vec3F; } else if (type == typeof(Vector4)) { return CtrlType.Vec4F; } else if (type == typeof(Color)) { return CtrlType.ColorF; } else if (type == typeof(Color32)) { return CtrlType.Color; } return CtrlType.Unknown; } public static bool IsSupport(Type type) { if (type == typeof(string) || type == typeof(bool) || type == typeof(float) || type == typeof(int) || type == typeof(Vector2) || type == typeof(Vector3) || type == typeof(Vector4) || type == typeof(Color) || type == typeof(Color32) ) { return true; } return false; } public static void SetVec2(Vector2 vec2, float[] ary_f) { ary_f[0] = vec2.x; ary_f[1] = vec2.y; } public static void SetVec3(Vector3 vec3, float[] ary_f) { ary_f[0] = vec3.x; ary_f[1] = vec3.y; ary_f[2] = vec3.z; } public static void SetVec4(Vector4 vec4, float[] ary_f) { ary_f[0] = vec4.x; ary_f[1] = vec4.y; ary_f[2] = vec4.z; ary_f[3] = vec4.w; } public static void SetColor(Color clr, float[] ary_f) { ary_f[0] = clr.r; ary_f[1] = clr.g; ary_f[2] = clr.b; ary_f[3] = clr.a; } public static void SetColor32(Color32 clr, byte[] ary_b) { ary_b[0] = clr.r; ary_b[1] = clr.g; ary_b[2] = clr.b; ary_b[3] = clr.a; } public delegate void OnFoundAttribues(object sender, object behavior, FieldInfo info, UltraControlsAttribute ultra_attr, RangeAttribute range_attr); public static bool FindUltraControlsAttribues (Component component, UltraControlsAttribute.BindingFlag uc_flag, OnFoundAttribues dele) { if (dele == null) { return false; } BindingFlags sys_binding_flag = BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public; sf_FindAttribuesFromComponent (component, sys_binding_flag, uc_flag, dele); var animators = component.gameObject.GetComponentsInChildren(true); foreach (Animator animator in animators) { if (animator == null) continue; var behaviours = animator.GetBehaviours(); foreach (StateMachineBehaviour behaviour in behaviours) { sf_FindAttribuesFromBehavior(component, behaviour, sys_binding_flag, uc_flag, dele); }//behaviours }//animators return false; } private static void sf_FindAttribuesFromComponent (Component sender, BindingFlags sys_flag, UltraControlsAttribute.BindingFlag uc_flag , OnFoundAttribues dele) { var components = sender.gameObject.GetComponentsInChildren(true); foreach (T1 component in components) { if (component == null) continue; sf_FindAttribuesFromBehavior(sender, component, sys_flag, uc_flag, dele); }//monos } private static void sf_FindAttribuesFromBehavior (object sender, object behavior, BindingFlags sys_flag, UltraControlsAttribute.BindingFlag uc_flag, OnFoundAttribues dele) { foreach (FieldInfo field in (behavior.GetType().GetFields(sys_flag))) { UltraControlsAttribute attr_ultracontrols = null; RangeAttribute attr_range = null; foreach (object attribute in field.GetCustomAttributes(true)) { { var attr = attribute as UltraControlsAttribute; if (attr != null && attr.binding_flag == UltraControlsAttribute.BindingFlag.Getter) { attr_ultracontrols = attr; continue; } } { var attr = attribute as RangeAttribute; if (attr != null) { attr_range = attr; } } }//attributes if (attr_ultracontrols == null) { continue; } dele.Invoke(sender, behavior, field, attr_ultracontrols, attr_range); }//fields } #if UNITY_EDITOR //https://forum.unity3d.com/threads/how-to-get-the-local-identifier-in-file-for-scene-objects.265686/#post-1766415 //https://gist.github.com/DmitriyYukhanov/5d93a0a204c32db1dd45d7a86e1df87e private static PropertyInfo cachedInspectorModeInfo; public static long GetLocalIdentifierInFileForObject(UnityEngine.Object obj) { long id = 0; if (obj == null) { return id; } PropertyInfo cachedInspectorModeInfo = typeof(UnityEditor.SerializedObject).GetProperty("inspectorMode", BindingFlags.NonPublic | BindingFlags.Instance); UnityEditor.SerializedObject serializedObject = new UnityEditor.SerializedObject(obj); cachedInspectorModeInfo.SetValue(serializedObject, UnityEditor.InspectorMode.Debug, null); UnityEditor.SerializedProperty serializedProperty = serializedObject.FindProperty("m_LocalIdentfierInFile"); #if UNITY_5_PLUS id = serializedProperty.longValue; #else id = serializedProperty.intValue; #endif //if (id <= 0) //{ // UnityEditor.PrefabType prefabType = UnityEditor.PrefabUtility.GetPrefabType(obj); // if (prefabType != UnityEditor.PrefabType.None) // { // id = GetLocalIdentifierInFileForObject(UnityEditor.PrefabUtility.GetPrefabParent(obj)); // } // else // { // // this will work for the new objects in scene which weren't saved yet // id = obj.GetInstanceID(); // } //} // //if (id <= 0) //{ // UnityEngine.GameObject go = obj as UnityEngine.GameObject; // if (go != null) // { // id = go.transform.GetSiblingIndex(); // } //} return id; } #endif } }