You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

603 lines
19 KiB

#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<string, object>();
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<string, object> >(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<JsonVector2>(obj.ToString());
if (json_vec2 == null)
{
continue;
}
ctrl.valVector2 = json_vec2.To();
}
break;
case CtrlType.Vec3F:
{
JsonVector3 json_vec3 = JsonConvert.DeserializeObject<JsonVector3>(obj.ToString());
if (json_vec3 == null)
{
continue;
}
ctrl.valVector3 = json_vec3.To();
}
break;
case CtrlType.Vec4F:
{
JsonVector4 json_vec4 = JsonConvert.DeserializeObject<JsonVector4>(obj.ToString());
if (json_vec4 == null)
{
continue;
}
ctrl.valVector2 = json_vec4.To();
}
break;
case CtrlType.ColorF:
{
JsonColor json_color = JsonConvert.DeserializeObject<JsonColor>(obj.ToString());
if (json_color == null)
{
continue;
}
ctrl.valColor = json_color.To();
}
break;
case CtrlType.Color:
{
JsonColor32 json_color32 = JsonConvert.DeserializeObject<JsonColor32>(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<T>(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>(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 <MonoBehaviour>(component, sys_binding_flag, uc_flag, dele);
var animators = component.gameObject.GetComponentsInChildren<Animator>(true);
foreach (Animator animator in animators)
{
if (animator == null)
continue;
var behaviours = animator.GetBehaviours<StateMachineBehaviour>();
foreach (StateMachineBehaviour behaviour in behaviours)
{
sf_FindAttribuesFromBehavior(component, behaviour, sys_binding_flag, uc_flag, dele);
}//behaviours
}//animators
return false;
}
private static void sf_FindAttribuesFromComponent<T1> (Component sender, BindingFlags sys_flag, UltraControlsAttribute.BindingFlag uc_flag , OnFoundAttribues dele)
{
var components = sender.gameObject.GetComponentsInChildren<T1>(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
}
}