diff --git a/src/CppExplorer.cs b/src/CppExplorer.cs index 1f9b293..23349a8 100644 --- a/src/CppExplorer.cs +++ b/src/CppExplorer.cs @@ -16,7 +16,7 @@ namespace Explorer public const string ID = "com.sinai.cppexplorer"; public const string NAME = "IL2CPP Runtime Explorer"; - public const string VERSION = "1.3.0"; + public const string VERSION = "1.3.1"; public const string AUTHOR = "Sinai"; // fields diff --git a/src/CppExplorer.csproj b/src/CppExplorer.csproj index a2274dd..6c1be1c 100644 --- a/src/CppExplorer.csproj +++ b/src/CppExplorer.csproj @@ -112,7 +112,6 @@ - diff --git a/src/ILBehaviour.cs b/src/ILBehaviour.cs deleted file mode 100644 index a00d88d..0000000 --- a/src/ILBehaviour.cs +++ /dev/null @@ -1,33 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using UnityEngine; -using MelonLoader; -using UnhollowerRuntimeLib; - -namespace Explorer -{ - //public class ILBehaviour : MonoBehaviour - //{ - // public ILBehaviour(IntPtr intPtr) : base(intPtr) { } - - // public static T AddToGameObject(GameObject _go) where T : ILBehaviour - // { - // Il2CppSystem.Type ilType = UnhollowerRuntimeLib.Il2CppType.Of(); - - // if (ilType == null) - // { - // MelonLogger.Log("Error - could not get MB as ilType"); - // return null; - // } - - // var obj = typeof(T) - // .GetConstructor(new Type[] { typeof(IntPtr) }) - // .Invoke(new object[] { _go.AddComponent(UnhollowerRuntimeLib.Il2CppType.Of()).Pointer }); - - // return (T)obj; - // } - //} -} diff --git a/src/Inspectors/ReflectionWindow.cs b/src/Inspectors/ReflectionWindow.cs index 0d1ba66..aafb519 100644 --- a/src/Inspectors/ReflectionWindow.cs +++ b/src/Inspectors/ReflectionWindow.cs @@ -93,9 +93,13 @@ namespace Explorer return; } - m_objectType = type; - GetFields(m_object); - GetProperties(m_object); + try + { + m_objectType = type; + GetFields(m_object); + GetProperties(m_object); + } + catch { } UpdateValues(); } @@ -276,7 +280,7 @@ namespace Explorer public static bool IsList(Type t) { - return t.IsGenericType + return t.IsGenericType && t.GetGenericTypeDefinition() is Type typeDef && (typeDef.IsAssignableFrom(typeof(List<>)) || typeDef.IsAssignableFrom(typeof(Il2CppSystem.Collections.Generic.List<>))); } @@ -292,8 +296,20 @@ namespace Explorer foreach (var type in types) { - foreach (var pi in type.GetProperties(At.flags)) + PropertyInfo[] propInfos = new PropertyInfo[0]; + + try { + propInfos = type.GetProperties(At.flags); + } + catch (TypeLoadException) + { + MelonLogger.Log($"Couldn't get Properties for Type '{type.Name}', it may not support Il2Cpp Reflection at the moment."); + } + + foreach (var pi in propInfos) + { + // this member causes a crash when inspected, so just skipping it for now. if (pi.Name == "Il2CppType") { continue; @@ -335,7 +351,7 @@ namespace Explorer } } } - + /* ********************* * PROPERTYINFO HOLDER @@ -346,6 +362,7 @@ namespace Explorer public Type classType; public PropertyInfo propInfo; public object m_value; + public bool IsExpanded; public PropertyInfoHolder(Type _type, PropertyInfo _propInfo) { @@ -355,14 +372,7 @@ namespace Explorer public void Draw(ReflectionWindow window) { - if (propInfo.CanWrite) - { - UIStyles.DrawMember(ref m_value, propInfo.PropertyType.Name, propInfo.Name, window.m_rect, window.m_object, SetValue); - } - else - { - UIStyles.DrawMember(ref m_value, propInfo.PropertyType.Name, propInfo.Name, window.m_rect, window.m_object); - } + UIStyles.DrawMember(ref m_value, ref this.IsExpanded, this.propInfo, window.m_rect, window.m_object, SetValue); } public void UpdateValue(object obj) @@ -389,15 +399,15 @@ namespace Explorer } catch (Exception e) { - //MelonLogger.Log("Exception on PropertyInfoHolder.UpdateValue, Name: " + this.propInfo.Name); - //MelonLogger.Log(e.GetType() + ", " + e.Message); + MelonLogger.Log("Exception on PropertyInfoHolder.UpdateValue, Name: " + this.propInfo.Name); + MelonLogger.Log(e.GetType() + ", " + e.Message); - //var inner = e.InnerException; - //while (inner != null) - //{ - // MelonLogger.Log("inner: " + inner.GetType() + ", " + inner.Message); - // inner = inner.InnerException; - //} + var inner = e.InnerException; + while (inner != null) + { + MelonLogger.Log("inner: " + inner.GetType() + ", " + inner.Message); + inner = inner.InnerException; + } m_value = null; } @@ -473,6 +483,7 @@ namespace Explorer public Type classType; public FieldInfo fieldInfo; public object m_value; + public bool IsExpanded; public FieldInfoHolder(Type _type, FieldInfo _fieldInfo) { @@ -487,16 +498,7 @@ namespace Explorer public void Draw(ReflectionWindow window) { - bool canSet = !(fieldInfo.IsLiteral && !fieldInfo.IsInitOnly); - - if (canSet) - { - UIStyles.DrawMember(ref m_value, fieldInfo.FieldType.Name, fieldInfo.Name, window.m_rect, window.m_object, SetValue); - } - else - { - UIStyles.DrawMember(ref m_value, fieldInfo.FieldType.Name, fieldInfo.Name, window.m_rect, window.m_object); - } + UIStyles.DrawMember(ref m_value, ref this.IsExpanded, this.fieldInfo, window.m_rect, window.m_object, SetValue); } public void SetValue(object obj) diff --git a/src/MainMenu/Pages/Console/REPL.cs b/src/MainMenu/Pages/Console/REPL.cs index 97ab678..31ff80d 100644 --- a/src/MainMenu/Pages/Console/REPL.cs +++ b/src/MainMenu/Pages/Console/REPL.cs @@ -36,17 +36,17 @@ namespace Explorer return MB.FindAll(); } - [Documentation("runCoroutine(enumerator) - runs an IEnumerator as a Unity coroutine.")] - public static object runCoroutine(IEnumerator i) - { - return MB.RunCoroutine(i); - } + //[Documentation("runCoroutine(enumerator) - runs an IEnumerator as a Unity coroutine.")] + //public static object runCoroutine(IEnumerator i) + //{ + // return MB.RunCoroutine(i); + //} - [Documentation("endCoroutine(co) - ends a Unity coroutine.")] - public static void endCoroutine(Coroutine c) - { - MB.EndCoroutine(c); - } + //[Documentation("endCoroutine(co) - ends a Unity coroutine.")] + //public static void endCoroutine(Coroutine c) + //{ + // MB.EndCoroutine(c); + //} ////[Documentation("type() - obtain type info about a type T. Provides some Reflection helpers.")] ////public static TypeHelper type() diff --git a/src/MainMenu/Pages/Console/REPLHelper.cs b/src/MainMenu/Pages/Console/REPLHelper.cs index d228761..e31ff73 100644 --- a/src/MainMenu/Pages/Console/REPLHelper.cs +++ b/src/MainMenu/Pages/Console/REPLHelper.cs @@ -21,14 +21,14 @@ namespace Explorer return FindObjectsOfType(); } - public object RunCoroutine(IEnumerator enumerator) - { - return MelonCoroutines.Start(enumerator); - } + //public object RunCoroutine(IEnumerator enumerator) + //{ + // return MelonCoroutines.Start(enumerator); + //} - public void EndCoroutine(Coroutine c) - { - StopCoroutine(c); - } + //public void EndCoroutine(Coroutine c) + //{ + // StopCoroutine(c); + //} } } \ No newline at end of file diff --git a/src/MainMenu/Pages/ScenePage.cs b/src/MainMenu/Pages/ScenePage.cs index aac139f..af615b1 100644 --- a/src/MainMenu/Pages/ScenePage.cs +++ b/src/MainMenu/Pages/ScenePage.cs @@ -20,12 +20,13 @@ namespace Explorer // gameobject list private Transform m_currentTransform; - private List m_objectList = new List(); + private List m_objectList = new List(); + private float m_timeOfLastUpdate = -1f; // search bar private bool m_searching = false; private string m_searchInput = ""; - private List m_searchResults = new List(); + private List m_searchResults = new List(); // ------------ Init and Update ------------ // @@ -40,17 +41,24 @@ namespace Explorer m_currentTransform = null; CancelSearch(); - } public override void Update() { + if (Time.time - m_timeOfLastUpdate < 1f) + { + return; + } + m_timeOfLastUpdate = Time.time; + + var start = Time.realtimeSinceStartup; + if (!m_searching) { - m_objectList = new List(); + m_objectList = new List(); if (m_currentTransform) { - var noChildren = new List(); + var endAppend = new List(); for (int i = 0; i < m_currentTransform.childCount; i++) { var child = m_currentTransform.GetChild(i); @@ -58,13 +66,13 @@ namespace Explorer if (child) { if (child.childCount > 0) - m_objectList.Add(child.gameObject); + m_objectList.Add(new GameObjectCache(child.gameObject)); else - noChildren.Add(child.gameObject); + endAppend.Add(new GameObjectCache(child.gameObject)); } } - m_objectList.AddRange(noChildren); - noChildren = null; + m_objectList.AddRange(endAppend); + endAppend = null; } else { @@ -74,11 +82,11 @@ namespace Explorer // add objects with children first foreach (var obj in rootObjects.Where(x => x.transform.childCount > 0)) { - m_objectList.Add(obj); + m_objectList.Add(new GameObjectCache(obj)); } foreach (var obj in rootObjects.Where(x => x.transform.childCount == 0)) { - m_objectList.Add(obj); + m_objectList.Add(new GameObjectCache(obj)); } } } @@ -161,10 +169,13 @@ namespace Explorer if (m_objectList.Count > 0) { + var start = Time.realtimeSinceStartup; foreach (var obj in m_objectList) { - UIStyles.GameobjButton(obj, SetTransformTarget, true, MainMenu.MainRect.width - 170); + //UIStyles.GameobjButton(obj, SetTransformTarget, true, MainMenu.MainRect.width - 170); + UIStyles.FastGameobjButton(obj.RefGameObject, obj.EnabledColor, obj.Label, obj.RefGameObject.activeSelf, SetTransformTarget, true, MainMenu.MainRect.width - 170); } + var diff = Time.realtimeSinceStartup - start; } else { @@ -184,7 +195,8 @@ namespace Explorer { foreach (var obj in m_searchResults) { - UIStyles.GameobjButton(obj, SetTransformTarget, true, MainMenu.MainRect.width - 170); + //UIStyles.GameobjButton(obj, SetTransformTarget, true, MainMenu.MainRect.width - 170); + UIStyles.FastGameobjButton(obj.RefGameObject, obj.EnabledColor, obj.Label, obj.RefGameObject.activeSelf, SetTransformTarget, true, MainMenu.MainRect.width - 170); } } else @@ -232,19 +244,54 @@ namespace Explorer m_searching = false; } - public List SearchSceneObjects(string _search) + public List SearchSceneObjects(string _search) { - var matches = new List(); + var matches = new List(); foreach (var obj in Resources.FindObjectsOfTypeAll()) { if (obj.name.ToLower().Contains(_search.ToLower()) && obj.scene.name == m_currentScene) { - matches.Add(obj); + matches.Add(new GameObjectCache(obj)); } } return matches; } + + public class GameObjectCache + { + public GameObject RefGameObject; + public string Label; + public Color EnabledColor; + public int ChildCount; + + public GameObjectCache(GameObject obj) + { + RefGameObject = obj; + ChildCount = obj.transform.childCount; + + Label = (ChildCount > 0) ? "[" + obj.transform.childCount + " children] " : ""; + Label += obj.name; + + bool enabled = obj.activeSelf; + int childCount = obj.transform.childCount; + if (enabled) + { + if (childCount > 0) + { + EnabledColor = Color.green; + } + else + { + EnabledColor = UIStyles.LightGreen; + } + } + else + { + EnabledColor = Color.red; + } + } + } } } diff --git a/src/MainMenu/Pages/SearchPage.cs b/src/MainMenu/Pages/SearchPage.cs index 603de38..c4df37d 100644 --- a/src/MainMenu/Pages/SearchPage.cs +++ b/src/MainMenu/Pages/SearchPage.cs @@ -91,7 +91,8 @@ namespace Explorer { var obj = m_searchResults[i]; - UIStyles.DrawValue(ref obj, _temprect); + bool _ = false; + UIStyles.DrawValue(ref obj, _temprect, ref _); } } else @@ -262,7 +263,6 @@ namespace Explorer { var findType = CppExplorer.GetType(_type); type = Il2CppSystem.Type.GetType(findType.AssemblyQualifiedName); - MelonLogger.Log("Got type: " + type.AssemblyQualifiedName); } catch (Exception e) { diff --git a/src/UIStyles.cs b/src/UIStyles.cs index a605092..d21224d 100644 --- a/src/UIStyles.cs +++ b/src/UIStyles.cs @@ -5,7 +5,7 @@ using System.Linq; using System.Reflection; using System.Text; using Il2CppSystem.Collections; -using Il2CppSystem.Reflection; +//using Il2CppSystem.Reflection; using MelonLoader; using UnhollowerBaseLib; using UnityEngine; @@ -15,6 +15,8 @@ namespace Explorer { public class UIStyles { + public static Color LightGreen = new Color(Color.green.r - 0.3f, Color.green.g - 0.3f, Color.green.b - 0.3f); + public static GUISkin WindowSkin { get @@ -115,42 +117,48 @@ namespace Explorer // helper for drawing a styled button for a GameObject or Transform public static void GameobjButton(GameObject obj, Action specialInspectMethod = null, bool showSmallInspectBtn = true, float width = 380) { - if (obj == null) + bool children = obj.transform.childCount > 0; + + string label = children ? "[" + obj.transform.childCount + " children] " : ""; + label += obj.name; + + bool enabled = obj.activeSelf; + int childCount = obj.transform.childCount; + Color color; + + if (enabled) + { + if (childCount > 0) + { + color = Color.green; + } + else + { + color = LightGreen; + } + } + else + { + color = Color.red; + } + + FastGameobjButton(obj, color, label, obj.activeSelf, specialInspectMethod, showSmallInspectBtn, width); + } + + public static void FastGameobjButton(GameObject obj, Color activeColor, string label, bool enabled, Action specialInspectMethod = null, bool showSmallInspectBtn = true, float width = 380) + { + if (!obj) { GUILayout.Label("null", null); return; } - bool enabled = obj.activeSelf; - bool children = obj.transform.childCount > 0; + // ------ toggle active button ------ GUILayout.BeginHorizontal(null); GUI.skin.button.alignment = TextAnchor.UpperLeft; - // ------ build name ------ - - string label = children ? "[" + obj.transform.childCount + " children] " : ""; - label += obj.name; - - // ------ Color ------- - - if (enabled) - { - if (children) - { - GUI.color = Color.green; - } - else - { - GUI.color = new Color(Color.green.r - 0.3f, Color.green.g - 0.3f, Color.green.b - 0.3f); - } - } - else - { - GUI.color = Color.red; - } - - // ------ toggle active button ------ + GUI.color = activeColor; enabled = GUILayout.Toggle(enabled, "", new GUILayoutOption[] { GUILayout.Width(18) }); if (obj.activeSelf != enabled) @@ -188,84 +196,114 @@ namespace Explorer GUILayout.EndHorizontal(); } - public static void DrawMember(ref object value, string valueType, string memberName, Rect rect, object setTarget = null, Action setAction = null, float labelWidth = 180, bool autoSet = false) + public static void DrawMember(ref object value, ref bool isExpanded, MemberInfo memberInfo, Rect rect, object setTarget = null, Action setAction = null, float labelWidth = 180, bool autoSet = false) { - GUILayout.Label("" + memberName + ":", new GUILayoutOption[] { GUILayout.Width(labelWidth) }); + GUILayout.Label("" + memberInfo.Name + ":", new GUILayoutOption[] { GUILayout.Width(labelWidth) }); - DrawValue(ref value, rect, valueType, memberName, setTarget, setAction, autoSet); + string valueType = ""; + bool canWrite = true; + if (memberInfo is FieldInfo fi) + { + valueType = fi.FieldType.Name; + canWrite = !(fi.IsLiteral && !fi.IsInitOnly); + } + else if (memberInfo is PropertyInfo pi) + { + valueType = pi.PropertyType.Name; + canWrite = pi.CanWrite; + } + + DrawValue(ref value, rect, ref isExpanded, valueType, (canWrite ? setTarget : null), (canWrite ? setAction : null), autoSet); } - public static void DrawValue(ref object value, Rect rect, string nullValueType = null, string memberName = null, object setTarget = null, Action setAction = null, bool autoSet = false) + public static void DrawValue(ref object value, Rect rect, ref bool isExpanded, string nullValueType = null, object setTarget = null, Action setAction = null, bool autoSet = false) { if (value == null) { GUILayout.Label("null (" + nullValueType + ")", null); + return; } - else + + var valueType = value.GetType(); + if (valueType.IsPrimitive || value.GetType() == typeof(string)) { - var valueType = value.GetType(); - if (valueType.IsPrimitive || value.GetType() == typeof(string)) + DrawPrimitive(ref value, rect, setTarget, setAction); + } + else if (valueType == typeof(GameObject) || valueType == typeof(Transform)) + { + GameObject go; + if (value.GetType() == typeof(Transform)) { - DrawPrimitive(ref value, rect, setTarget, setAction); + go = (value as Transform).gameObject; } - else if (valueType == typeof(GameObject) || valueType == typeof(Transform)) + else { - GameObject go; - if (value.GetType() == typeof(Transform)) - { - go = (value as Transform).gameObject; - } - else - { - go = (value as GameObject); - } - - UIStyles.GameobjButton(go, null, false, rect.width - 250); + go = (value as GameObject); } - else if (valueType.IsEnum) - { - if (setAction != null) - { - if (GUILayout.Button("<", new GUILayoutOption[] { GUILayout.Width(25) })) - { - SetEnum(ref value, -1); - setAction.Invoke(setTarget); - } - if (GUILayout.Button(">", new GUILayoutOption[] { GUILayout.Width(25) })) - { - SetEnum(ref value, 1); - setAction.Invoke(setTarget); - } - } - GUILayout.Label(value.ToString(), null); + GameobjButton(go, null, false, rect.width - 250); + } + else if (valueType.IsEnum) + { + if (setAction != null) + { + if (GUILayout.Button("<", new GUILayoutOption[] { GUILayout.Width(25) })) + { + SetEnum(ref value, -1); + setAction.Invoke(setTarget); + } + if (GUILayout.Button(">", new GUILayoutOption[] { GUILayout.Width(25) })) + { + SetEnum(ref value, 1); + setAction.Invoke(setTarget); + } } - else if (value is System.Collections.IEnumerable || ReflectionWindow.IsList(valueType)) + + GUILayout.Label(value.ToString(), null); + } + else if (value is System.Collections.IEnumerable || ReflectionWindow.IsList(valueType)) + { + System.Collections.IEnumerable enumerable; + + if (value is System.Collections.IEnumerable isEnumerable) { - System.Collections.IEnumerable enumerable; + enumerable = isEnumerable; + } + else + { + var listValueType = value.GetType().GetGenericArguments()[0]; + var listType = typeof(Il2CppSystem.Collections.Generic.List<>).MakeGenericType(new Type[] { listValueType }); + var method = listType.GetMethod("ToArray"); + enumerable = (System.Collections.IEnumerable)method.Invoke(value, new object[0]); + } - if (value is System.Collections.IEnumerable isEnumerable) + int count = enumerable.Cast().Count(); + + if (!isExpanded) + { + if (GUILayout.Button("v", new GUILayoutOption[] { GUILayout.Width(25) })) { - enumerable = isEnumerable; + isExpanded = true; } - else + } + else + { + if (GUILayout.Button("^", new GUILayoutOption[] { GUILayout.Width(25) })) { - var listValueType = value.GetType().GetGenericArguments()[0]; - var listType = typeof(Il2CppSystem.Collections.Generic.List<>).MakeGenericType(new Type[] { listValueType }); - var method = listType.GetMethod("ToArray"); - enumerable = (System.Collections.IEnumerable)method.Invoke(value, new object[0]); + isExpanded = false; } + } - int count = enumerable.Cast().Count(); - - GUI.skin.button.alignment = TextAnchor.MiddleLeft; - string btnLabel = "[" + count + "] " + valueType + ""; - if (GUILayout.Button(btnLabel, new GUILayoutOption[] { GUILayout.MaxWidth(rect.width - 230) })) - { - WindowManager.InspectObject(value, out bool _); - } - GUI.skin.button.alignment = TextAnchor.MiddleCenter; + GUI.skin.button.alignment = TextAnchor.MiddleLeft; + string btnLabel = "[" + count + "] " + valueType + ""; + if (GUILayout.Button(btnLabel, new GUILayoutOption[] { GUILayout.MaxWidth(rect.width - 260) })) + { + WindowManager.InspectObject(value, out bool _); + } + GUI.skin.button.alignment = TextAnchor.MiddleCenter; + if (isExpanded) + { var enumerator = enumerable.GetEnumerator(); if (enumerator != null) { @@ -315,49 +353,68 @@ namespace Explorer } } } - else + } + else + { + var label = value.ToString(); + + if (valueType == typeof(Object)) { - var label = value.ToString(); - - if (valueType == typeof(Object)) - { - label = (value as Object).name; - } - else if (value is Vector4 vec4) - { - label = vec4.ToString(); - } - else if (value is Vector3 vec3) - { - label = vec3.ToString(); - } - else if (value is Vector2 vec2) - { - label = vec2.ToString(); - } - else if (value is Rect rec) - { - label = rec.ToString(); - } - else if (value is Matrix4x4 matrix) - { - label = matrix.ToString(); - } - else if (value is Color col) - { - label = col.ToString(); - } - - GUI.skin.button.alignment = TextAnchor.MiddleLeft; - if (GUILayout.Button("" + label + "", new GUILayoutOption[] { GUILayout.MaxWidth(rect.width - 230) })) - { - WindowManager.InspectObject(value, out bool _); - } - GUI.skin.button.alignment = TextAnchor.MiddleCenter; + label = (value as Object).name; } + else if (value is Vector4 vec4) + { + label = vec4.ToString(); + } + else if (value is Vector3 vec3) + { + label = vec3.ToString(); + } + else if (value is Vector2 vec2) + { + label = vec2.ToString(); + } + else if (value is Rect rec) + { + label = rec.ToString(); + } + else if (value is Matrix4x4 matrix) + { + label = matrix.ToString(); + } + else if (value is Color col) + { + label = col.ToString(); + } + + GUI.skin.button.alignment = TextAnchor.MiddleLeft; + if (GUILayout.Button("" + label + "", new GUILayoutOption[] { GUILayout.MaxWidth(rect.width - 230) })) + { + WindowManager.InspectObject(value, out bool _); + } + GUI.skin.button.alignment = TextAnchor.MiddleCenter; } } + //public static void DrawMember(ref object value, string valueType, string memberName, Rect rect, object setTarget = null, Action setAction = null, float labelWidth = 180, bool autoSet = false) + //{ + // GUILayout.Label("" + memberName + ":", new GUILayoutOption[] { GUILayout.Width(labelWidth) }); + + // DrawValue(ref value, rect, valueType, memberName, setTarget, setAction, autoSet); + //} + + //public static void DrawValue(ref object value, Rect rect, string nullValueType = null, string memberName = null, object setTarget = null, Action setAction = null, bool autoSet = false) + //{ + // if (value == null) + // { + // GUILayout.Label("null (" + nullValueType + ")", null); + // } + // else + // { + + // } + //} + // Helper for drawing primitive values (with Apply button) public static void DrawPrimitive(ref object value, Rect m_rect, object setTarget = null, Action setAction = null, bool autoSet = false) @@ -387,10 +444,10 @@ namespace Explorer } else { - value = GUILayout.TextField(value.ToString(), new GUILayoutOption[] { GUILayout.MaxWidth(m_rect.width - 260) }); + value = GUILayout.TextField(value.ToString(), new GUILayoutOption[] { GUILayout.MaxWidth(m_rect.width - 260) }); } - if (autoSet || (allowSet && GUILayout.Button("Apply", new GUILayoutOption[] { GUILayout.Width(60) }))) + if (autoSet || (allowSet && GUILayout.Button("Apply", new GUILayoutOption[] { GUILayout.Width(60) }))) { setAction.Invoke(setTarget); } diff --git a/src_2018/CppExplorer.cs b/src_2018/CppExplorer.cs index 1f9b293..23349a8 100644 --- a/src_2018/CppExplorer.cs +++ b/src_2018/CppExplorer.cs @@ -16,7 +16,7 @@ namespace Explorer public const string ID = "com.sinai.cppexplorer"; public const string NAME = "IL2CPP Runtime Explorer"; - public const string VERSION = "1.3.0"; + public const string VERSION = "1.3.1"; public const string AUTHOR = "Sinai"; // fields diff --git a/src_2018/CppExplorer.csproj b/src_2018/CppExplorer.csproj index b195b77..1657b75 100644 --- a/src_2018/CppExplorer.csproj +++ b/src_2018/CppExplorer.csproj @@ -104,7 +104,6 @@ - diff --git a/src_2018/ILBehaviour.cs b/src_2018/ILBehaviour.cs deleted file mode 100644 index a00d88d..0000000 --- a/src_2018/ILBehaviour.cs +++ /dev/null @@ -1,33 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using UnityEngine; -using MelonLoader; -using UnhollowerRuntimeLib; - -namespace Explorer -{ - //public class ILBehaviour : MonoBehaviour - //{ - // public ILBehaviour(IntPtr intPtr) : base(intPtr) { } - - // public static T AddToGameObject(GameObject _go) where T : ILBehaviour - // { - // Il2CppSystem.Type ilType = UnhollowerRuntimeLib.Il2CppType.Of(); - - // if (ilType == null) - // { - // MelonLogger.Log("Error - could not get MB as ilType"); - // return null; - // } - - // var obj = typeof(T) - // .GetConstructor(new Type[] { typeof(IntPtr) }) - // .Invoke(new object[] { _go.AddComponent(UnhollowerRuntimeLib.Il2CppType.Of()).Pointer }); - - // return (T)obj; - // } - //} -} diff --git a/src_2018/Inspectors/ReflectionWindow.cs b/src_2018/Inspectors/ReflectionWindow.cs index 0d1ba66..aafb519 100644 --- a/src_2018/Inspectors/ReflectionWindow.cs +++ b/src_2018/Inspectors/ReflectionWindow.cs @@ -93,9 +93,13 @@ namespace Explorer return; } - m_objectType = type; - GetFields(m_object); - GetProperties(m_object); + try + { + m_objectType = type; + GetFields(m_object); + GetProperties(m_object); + } + catch { } UpdateValues(); } @@ -276,7 +280,7 @@ namespace Explorer public static bool IsList(Type t) { - return t.IsGenericType + return t.IsGenericType && t.GetGenericTypeDefinition() is Type typeDef && (typeDef.IsAssignableFrom(typeof(List<>)) || typeDef.IsAssignableFrom(typeof(Il2CppSystem.Collections.Generic.List<>))); } @@ -292,8 +296,20 @@ namespace Explorer foreach (var type in types) { - foreach (var pi in type.GetProperties(At.flags)) + PropertyInfo[] propInfos = new PropertyInfo[0]; + + try { + propInfos = type.GetProperties(At.flags); + } + catch (TypeLoadException) + { + MelonLogger.Log($"Couldn't get Properties for Type '{type.Name}', it may not support Il2Cpp Reflection at the moment."); + } + + foreach (var pi in propInfos) + { + // this member causes a crash when inspected, so just skipping it for now. if (pi.Name == "Il2CppType") { continue; @@ -335,7 +351,7 @@ namespace Explorer } } } - + /* ********************* * PROPERTYINFO HOLDER @@ -346,6 +362,7 @@ namespace Explorer public Type classType; public PropertyInfo propInfo; public object m_value; + public bool IsExpanded; public PropertyInfoHolder(Type _type, PropertyInfo _propInfo) { @@ -355,14 +372,7 @@ namespace Explorer public void Draw(ReflectionWindow window) { - if (propInfo.CanWrite) - { - UIStyles.DrawMember(ref m_value, propInfo.PropertyType.Name, propInfo.Name, window.m_rect, window.m_object, SetValue); - } - else - { - UIStyles.DrawMember(ref m_value, propInfo.PropertyType.Name, propInfo.Name, window.m_rect, window.m_object); - } + UIStyles.DrawMember(ref m_value, ref this.IsExpanded, this.propInfo, window.m_rect, window.m_object, SetValue); } public void UpdateValue(object obj) @@ -389,15 +399,15 @@ namespace Explorer } catch (Exception e) { - //MelonLogger.Log("Exception on PropertyInfoHolder.UpdateValue, Name: " + this.propInfo.Name); - //MelonLogger.Log(e.GetType() + ", " + e.Message); + MelonLogger.Log("Exception on PropertyInfoHolder.UpdateValue, Name: " + this.propInfo.Name); + MelonLogger.Log(e.GetType() + ", " + e.Message); - //var inner = e.InnerException; - //while (inner != null) - //{ - // MelonLogger.Log("inner: " + inner.GetType() + ", " + inner.Message); - // inner = inner.InnerException; - //} + var inner = e.InnerException; + while (inner != null) + { + MelonLogger.Log("inner: " + inner.GetType() + ", " + inner.Message); + inner = inner.InnerException; + } m_value = null; } @@ -473,6 +483,7 @@ namespace Explorer public Type classType; public FieldInfo fieldInfo; public object m_value; + public bool IsExpanded; public FieldInfoHolder(Type _type, FieldInfo _fieldInfo) { @@ -487,16 +498,7 @@ namespace Explorer public void Draw(ReflectionWindow window) { - bool canSet = !(fieldInfo.IsLiteral && !fieldInfo.IsInitOnly); - - if (canSet) - { - UIStyles.DrawMember(ref m_value, fieldInfo.FieldType.Name, fieldInfo.Name, window.m_rect, window.m_object, SetValue); - } - else - { - UIStyles.DrawMember(ref m_value, fieldInfo.FieldType.Name, fieldInfo.Name, window.m_rect, window.m_object); - } + UIStyles.DrawMember(ref m_value, ref this.IsExpanded, this.fieldInfo, window.m_rect, window.m_object, SetValue); } public void SetValue(object obj) diff --git a/src_2018/MainMenu/Pages/Console/REPL.cs b/src_2018/MainMenu/Pages/Console/REPL.cs index 97ab678..31ff80d 100644 --- a/src_2018/MainMenu/Pages/Console/REPL.cs +++ b/src_2018/MainMenu/Pages/Console/REPL.cs @@ -36,17 +36,17 @@ namespace Explorer return MB.FindAll(); } - [Documentation("runCoroutine(enumerator) - runs an IEnumerator as a Unity coroutine.")] - public static object runCoroutine(IEnumerator i) - { - return MB.RunCoroutine(i); - } + //[Documentation("runCoroutine(enumerator) - runs an IEnumerator as a Unity coroutine.")] + //public static object runCoroutine(IEnumerator i) + //{ + // return MB.RunCoroutine(i); + //} - [Documentation("endCoroutine(co) - ends a Unity coroutine.")] - public static void endCoroutine(Coroutine c) - { - MB.EndCoroutine(c); - } + //[Documentation("endCoroutine(co) - ends a Unity coroutine.")] + //public static void endCoroutine(Coroutine c) + //{ + // MB.EndCoroutine(c); + //} ////[Documentation("type() - obtain type info about a type T. Provides some Reflection helpers.")] ////public static TypeHelper type() diff --git a/src_2018/MainMenu/Pages/Console/REPLHelper.cs b/src_2018/MainMenu/Pages/Console/REPLHelper.cs index d228761..e31ff73 100644 --- a/src_2018/MainMenu/Pages/Console/REPLHelper.cs +++ b/src_2018/MainMenu/Pages/Console/REPLHelper.cs @@ -21,14 +21,14 @@ namespace Explorer return FindObjectsOfType(); } - public object RunCoroutine(IEnumerator enumerator) - { - return MelonCoroutines.Start(enumerator); - } + //public object RunCoroutine(IEnumerator enumerator) + //{ + // return MelonCoroutines.Start(enumerator); + //} - public void EndCoroutine(Coroutine c) - { - StopCoroutine(c); - } + //public void EndCoroutine(Coroutine c) + //{ + // StopCoroutine(c); + //} } } \ No newline at end of file diff --git a/src_2018/MainMenu/Pages/ScenePage.cs b/src_2018/MainMenu/Pages/ScenePage.cs index 60b4ed7..431b03c 100644 --- a/src_2018/MainMenu/Pages/ScenePage.cs +++ b/src_2018/MainMenu/Pages/ScenePage.cs @@ -20,12 +20,13 @@ namespace Explorer // gameobject list private Transform m_currentTransform; - private List m_objectList = new List(); + private List m_objectList = new List(); + private float m_timeOfLastUpdate = -1f; // search bar private bool m_searching = false; private string m_searchInput = ""; - private List m_searchResults = new List(); + private List m_searchResults = new List(); // ------------ Init and Update ------------ // @@ -40,17 +41,24 @@ namespace Explorer m_currentTransform = null; CancelSearch(); - } public override void Update() { + if (Time.time - m_timeOfLastUpdate < 1f) + { + return; + } + m_timeOfLastUpdate = Time.time; + + var start = Time.realtimeSinceStartup; + if (!m_searching) { - m_objectList = new List(); + m_objectList = new List(); if (m_currentTransform) { - var noChildren = new List(); + var endAppend = new List(); for (int i = 0; i < m_currentTransform.childCount; i++) { var child = m_currentTransform.GetChild(i); @@ -58,13 +66,13 @@ namespace Explorer if (child) { if (child.childCount > 0) - m_objectList.Add(child.gameObject); + m_objectList.Add(new GameObjectCache(child.gameObject)); else - noChildren.Add(child.gameObject); + endAppend.Add(new GameObjectCache(child.gameObject)); } } - m_objectList.AddRange(noChildren); - noChildren = null; + m_objectList.AddRange(endAppend); + endAppend = null; } else { @@ -74,11 +82,11 @@ namespace Explorer // add objects with children first foreach (var obj in rootObjects.Where(x => x.transform.childCount > 0)) { - m_objectList.Add(obj); + m_objectList.Add(new GameObjectCache(obj)); } foreach (var obj in rootObjects.Where(x => x.transform.childCount == 0)) { - m_objectList.Add(obj); + m_objectList.Add(new GameObjectCache(obj)); } } } @@ -120,7 +128,8 @@ namespace Explorer m_currentScene = scenes[index].name; } } - GUILayout.Label("" + m_currentScene + "", null); + GUILayout.Label("" + m_currentScene + "", null); //new GUILayoutOption[] { GUILayout.Width(250) }); + GUILayout.EndHorizontal(); // ----- GameObject Search ----- @@ -160,10 +169,13 @@ namespace Explorer if (m_objectList.Count > 0) { + var start = Time.realtimeSinceStartup; foreach (var obj in m_objectList) { - UIStyles.GameobjButton(obj, SetTransformTarget, true, MainMenu.MainRect.width - 170); + //UIStyles.GameobjButton(obj, SetTransformTarget, true, MainMenu.MainRect.width - 170); + UIStyles.FastGameobjButton(obj.RefGameObject, obj.EnabledColor, obj.Label, obj.RefGameObject.activeSelf, SetTransformTarget, true, MainMenu.MainRect.width - 170); } + var diff = Time.realtimeSinceStartup - start; } else { @@ -183,7 +195,8 @@ namespace Explorer { foreach (var obj in m_searchResults) { - UIStyles.GameobjButton(obj, SetTransformTarget, true, MainMenu.MainRect.width - 170); + //UIStyles.GameobjButton(obj, SetTransformTarget, true, MainMenu.MainRect.width - 170); + UIStyles.FastGameobjButton(obj.RefGameObject, obj.EnabledColor, obj.Label, obj.RefGameObject.activeSelf, SetTransformTarget, true, MainMenu.MainRect.width - 170); } } else @@ -231,19 +244,54 @@ namespace Explorer m_searching = false; } - public List SearchSceneObjects(string _search) + public List SearchSceneObjects(string _search) { - var matches = new List(); + var matches = new List(); foreach (var obj in Resources.FindObjectsOfTypeAll()) { if (obj.name.ToLower().Contains(_search.ToLower()) && obj.scene.name == m_currentScene) { - matches.Add(obj); + matches.Add(new GameObjectCache(obj)); } } return matches; } + + public class GameObjectCache + { + public GameObject RefGameObject; + public string Label; + public Color EnabledColor; + public int ChildCount; + + public GameObjectCache(GameObject obj) + { + RefGameObject = obj; + ChildCount = obj.transform.childCount; + + Label = (ChildCount > 0) ? "[" + obj.transform.childCount + " children] " : ""; + Label += obj.name; + + bool enabled = obj.activeSelf; + int childCount = obj.transform.childCount; + if (enabled) + { + if (childCount > 0) + { + EnabledColor = Color.green; + } + else + { + EnabledColor = UIStyles.LightGreen; + } + } + else + { + EnabledColor = Color.red; + } + } + } } } diff --git a/src_2018/MainMenu/Pages/SearchPage.cs b/src_2018/MainMenu/Pages/SearchPage.cs index 603de38..3bbd0a1 100644 --- a/src_2018/MainMenu/Pages/SearchPage.cs +++ b/src_2018/MainMenu/Pages/SearchPage.cs @@ -44,7 +44,7 @@ namespace Explorer private List m_searchResults = new List(); private Vector2 resultsScroll = Vector2.zero; - public override void Init() + public override void Init() { Instance = this; } @@ -54,7 +54,7 @@ namespace Explorer m_searchResults.Clear(); } - public override void Update() + public override void Update() { } @@ -91,7 +91,8 @@ namespace Explorer { var obj = m_searchResults[i]; - UIStyles.DrawValue(ref obj, _temprect); + bool _ = false; + UIStyles.DrawValue(ref obj, _temprect, ref _); } } else @@ -147,14 +148,14 @@ namespace Explorer { GUILayout.BeginHorizontal(null); GUI.skin.label.alignment = TextAnchor.MiddleRight; - GUILayout.Label("Custom Class:", new GUILayoutOption[] { GUILayout.Width(250) }); + GUILayout.Label("Custom Class:", new GUILayoutOption[] { GUILayout.Width(250) }); GUI.skin.label.alignment = TextAnchor.UpperLeft; - m_typeInput = GUILayout.TextField(m_typeInput, new GUILayoutOption[] { GUILayout.Width(250) }); + m_typeInput = GUILayout.TextField(m_typeInput, new GUILayoutOption[] { GUILayout.Width(250) }); GUILayout.EndHorizontal(); } GUILayout.BeginHorizontal(null); - GUILayout.Label("Scene Filter:", new GUILayoutOption[] { GUILayout.Width(100) }); + GUILayout.Label("Scene Filter:", new GUILayoutOption[] { GUILayout.Width(100) }); SceneFilterToggle(SceneFilter.Any, "Any", 60); SceneFilterToggle(SceneFilter.This, "This Scene", 100); SceneFilterToggle(SceneFilter.DontDestroy, "DontDestroyOnLoad", 140); @@ -262,7 +263,6 @@ namespace Explorer { var findType = CppExplorer.GetType(_type); type = Il2CppSystem.Type.GetType(findType.AssemblyQualifiedName); - MelonLogger.Log("Got type: " + type.AssemblyQualifiedName); } catch (Exception e) { @@ -372,7 +372,7 @@ namespace Explorer if (type == typeof(GameObject) || typeof(Component).IsAssignableFrom(type)) { var go = obj as GameObject ?? (obj as Component).gameObject; - + if (go != null && go.scene.name == CppExplorer.ActiveSceneName && go.scene.name != "DontDestroyOnLoad") { return true; diff --git a/src_2018/UIStyles.cs b/src_2018/UIStyles.cs index a605092..b7b1821 100644 --- a/src_2018/UIStyles.cs +++ b/src_2018/UIStyles.cs @@ -5,7 +5,7 @@ using System.Linq; using System.Reflection; using System.Text; using Il2CppSystem.Collections; -using Il2CppSystem.Reflection; +//using Il2CppSystem.Reflection; using MelonLoader; using UnhollowerBaseLib; using UnityEngine; @@ -15,6 +15,8 @@ namespace Explorer { public class UIStyles { + public static Color LightGreen = new Color(Color.green.r - 0.3f, Color.green.g - 0.3f, Color.green.b - 0.3f); + public static GUISkin WindowSkin { get @@ -115,42 +117,48 @@ namespace Explorer // helper for drawing a styled button for a GameObject or Transform public static void GameobjButton(GameObject obj, Action specialInspectMethod = null, bool showSmallInspectBtn = true, float width = 380) { - if (obj == null) + bool children = obj.transform.childCount > 0; + + string label = children ? "[" + obj.transform.childCount + " children] " : ""; + label += obj.name; + + bool enabled = obj.activeSelf; + int childCount = obj.transform.childCount; + Color color; + + if (enabled) + { + if (childCount > 0) + { + color = Color.green; + } + else + { + color = LightGreen; + } + } + else + { + color = Color.red; + } + + FastGameobjButton(obj, color, label, obj.activeSelf, specialInspectMethod, showSmallInspectBtn, width); + } + + public static void FastGameobjButton(GameObject obj, Color activeColor, string label, bool enabled, Action specialInspectMethod = null, bool showSmallInspectBtn = true, float width = 380) + { + if (!obj) { GUILayout.Label("null", null); return; } - bool enabled = obj.activeSelf; - bool children = obj.transform.childCount > 0; + // ------ toggle active button ------ GUILayout.BeginHorizontal(null); GUI.skin.button.alignment = TextAnchor.UpperLeft; - // ------ build name ------ - - string label = children ? "[" + obj.transform.childCount + " children] " : ""; - label += obj.name; - - // ------ Color ------- - - if (enabled) - { - if (children) - { - GUI.color = Color.green; - } - else - { - GUI.color = new Color(Color.green.r - 0.3f, Color.green.g - 0.3f, Color.green.b - 0.3f); - } - } - else - { - GUI.color = Color.red; - } - - // ------ toggle active button ------ + GUI.color = activeColor; enabled = GUILayout.Toggle(enabled, "", new GUILayoutOption[] { GUILayout.Width(18) }); if (obj.activeSelf != enabled) @@ -188,84 +196,114 @@ namespace Explorer GUILayout.EndHorizontal(); } - public static void DrawMember(ref object value, string valueType, string memberName, Rect rect, object setTarget = null, Action setAction = null, float labelWidth = 180, bool autoSet = false) + public static void DrawMember(ref object value, ref bool isExpanded, MemberInfo memberInfo, Rect rect, object setTarget = null, Action setAction = null, float labelWidth = 180, bool autoSet = false) { - GUILayout.Label("" + memberName + ":", new GUILayoutOption[] { GUILayout.Width(labelWidth) }); + GUILayout.Label("" + memberInfo.Name + ":", new GUILayoutOption[] { GUILayout.Width(labelWidth) }); - DrawValue(ref value, rect, valueType, memberName, setTarget, setAction, autoSet); + string valueType = ""; + bool canWrite = true; + if (memberInfo is FieldInfo fi) + { + valueType = fi.FieldType.Name; + canWrite = !(fi.IsLiteral && !fi.IsInitOnly); + } + else if (memberInfo is PropertyInfo pi) + { + valueType = pi.PropertyType.Name; + canWrite = pi.CanWrite; + } + + DrawValue(ref value, rect, ref isExpanded, valueType, (canWrite ? setTarget : null), (canWrite ? setAction : null), autoSet); } - public static void DrawValue(ref object value, Rect rect, string nullValueType = null, string memberName = null, object setTarget = null, Action setAction = null, bool autoSet = false) + public static void DrawValue(ref object value, Rect rect, ref bool isExpanded, string nullValueType = null, object setTarget = null, Action setAction = null, bool autoSet = false) { if (value == null) { GUILayout.Label("null (" + nullValueType + ")", null); + return; } - else + + var valueType = value.GetType(); + if (valueType.IsPrimitive || value.GetType() == typeof(string)) { - var valueType = value.GetType(); - if (valueType.IsPrimitive || value.GetType() == typeof(string)) + DrawPrimitive(ref value, rect, setTarget, setAction); + } + else if (valueType == typeof(GameObject) || valueType == typeof(Transform)) + { + GameObject go; + if (value.GetType() == typeof(Transform)) { - DrawPrimitive(ref value, rect, setTarget, setAction); + go = (value as Transform).gameObject; } - else if (valueType == typeof(GameObject) || valueType == typeof(Transform)) + else { - GameObject go; - if (value.GetType() == typeof(Transform)) - { - go = (value as Transform).gameObject; - } - else - { - go = (value as GameObject); - } - - UIStyles.GameobjButton(go, null, false, rect.width - 250); + go = (value as GameObject); } - else if (valueType.IsEnum) - { - if (setAction != null) - { - if (GUILayout.Button("<", new GUILayoutOption[] { GUILayout.Width(25) })) - { - SetEnum(ref value, -1); - setAction.Invoke(setTarget); - } - if (GUILayout.Button(">", new GUILayoutOption[] { GUILayout.Width(25) })) - { - SetEnum(ref value, 1); - setAction.Invoke(setTarget); - } - } - GUILayout.Label(value.ToString(), null); + GameobjButton(go, null, false, rect.width - 250); + } + else if (valueType.IsEnum) + { + if (setAction != null) + { + if (GUILayout.Button("<", new GUILayoutOption[] { GUILayout.Width(25) })) + { + SetEnum(ref value, -1); + setAction.Invoke(setTarget); + } + if (GUILayout.Button(">", new GUILayoutOption[] { GUILayout.Width(25) })) + { + SetEnum(ref value, 1); + setAction.Invoke(setTarget); + } } - else if (value is System.Collections.IEnumerable || ReflectionWindow.IsList(valueType)) + + GUILayout.Label(value.ToString(), null); + } + else if (value is System.Collections.IEnumerable || ReflectionWindow.IsList(valueType)) + { + System.Collections.IEnumerable enumerable; + + if (value is System.Collections.IEnumerable isEnumerable) { - System.Collections.IEnumerable enumerable; + enumerable = isEnumerable; + } + else + { + var listValueType = value.GetType().GetGenericArguments()[0]; + var listType = typeof(Il2CppSystem.Collections.Generic.List<>).MakeGenericType(new Type[] { listValueType }); + var method = listType.GetMethod("ToArray"); + enumerable = (System.Collections.IEnumerable)method.Invoke(value, new object[0]); + } - if (value is System.Collections.IEnumerable isEnumerable) + int count = enumerable.Cast().Count(); + + if (!isExpanded) + { + if (GUILayout.Button("v", new GUILayoutOption[] { GUILayout.Width(25) })) { - enumerable = isEnumerable; + isExpanded = true; } - else + } + else + { + if (GUILayout.Button("^", new GUILayoutOption[] { GUILayout.Width(25) })) { - var listValueType = value.GetType().GetGenericArguments()[0]; - var listType = typeof(Il2CppSystem.Collections.Generic.List<>).MakeGenericType(new Type[] { listValueType }); - var method = listType.GetMethod("ToArray"); - enumerable = (System.Collections.IEnumerable)method.Invoke(value, new object[0]); + isExpanded = false; } + } - int count = enumerable.Cast().Count(); - - GUI.skin.button.alignment = TextAnchor.MiddleLeft; - string btnLabel = "[" + count + "] " + valueType + ""; - if (GUILayout.Button(btnLabel, new GUILayoutOption[] { GUILayout.MaxWidth(rect.width - 230) })) - { - WindowManager.InspectObject(value, out bool _); - } - GUI.skin.button.alignment = TextAnchor.MiddleCenter; + GUI.skin.button.alignment = TextAnchor.MiddleLeft; + string btnLabel = "[" + count + "] " + valueType + ""; + if (GUILayout.Button(btnLabel, new GUILayoutOption[] { GUILayout.MaxWidth(rect.width - 260) })) + { + WindowManager.InspectObject(value, out bool _); + } + GUI.skin.button.alignment = TextAnchor.MiddleCenter; + if (isExpanded) + { var enumerator = enumerable.GetEnumerator(); if (enumerator != null) { @@ -315,49 +353,68 @@ namespace Explorer } } } - else + } + else + { + var label = value.ToString(); + + if (valueType == typeof(Object)) { - var label = value.ToString(); - - if (valueType == typeof(Object)) - { - label = (value as Object).name; - } - else if (value is Vector4 vec4) - { - label = vec4.ToString(); - } - else if (value is Vector3 vec3) - { - label = vec3.ToString(); - } - else if (value is Vector2 vec2) - { - label = vec2.ToString(); - } - else if (value is Rect rec) - { - label = rec.ToString(); - } - else if (value is Matrix4x4 matrix) - { - label = matrix.ToString(); - } - else if (value is Color col) - { - label = col.ToString(); - } - - GUI.skin.button.alignment = TextAnchor.MiddleLeft; - if (GUILayout.Button("" + label + "", new GUILayoutOption[] { GUILayout.MaxWidth(rect.width - 230) })) - { - WindowManager.InspectObject(value, out bool _); - } - GUI.skin.button.alignment = TextAnchor.MiddleCenter; + label = (value as Object).name; } + else if (value is Vector4 vec4) + { + label = vec4.ToString(); + } + else if (value is Vector3 vec3) + { + label = vec3.ToString(); + } + else if (value is Vector2 vec2) + { + label = vec2.ToString(); + } + else if (value is Rect rec) + { + label = rec.ToString(); + } + else if (value is Matrix4x4 matrix) + { + label = matrix.ToString(); + } + else if (value is Color col) + { + label = col.ToString(); + } + + GUI.skin.button.alignment = TextAnchor.MiddleLeft; + if (GUILayout.Button("" + label + "", new GUILayoutOption[] { GUILayout.MaxWidth(rect.width - 230) })) + { + WindowManager.InspectObject(value, out bool _); + } + GUI.skin.button.alignment = TextAnchor.MiddleCenter; } } + //public static void DrawMember(ref object value, string valueType, string memberName, Rect rect, object setTarget = null, Action setAction = null, float labelWidth = 180, bool autoSet = false) + //{ + // GUILayout.Label("" + memberName + ":", new GUILayoutOption[] { GUILayout.Width(labelWidth) }); + + // DrawValue(ref value, rect, valueType, memberName, setTarget, setAction, autoSet); + //} + + //public static void DrawValue(ref object value, Rect rect, string nullValueType = null, string memberName = null, object setTarget = null, Action setAction = null, bool autoSet = false) + //{ + // if (value == null) + // { + // GUILayout.Label("null (" + nullValueType + ")", null); + // } + // else + // { + + // } + //} + // Helper for drawing primitive values (with Apply button) public static void DrawPrimitive(ref object value, Rect m_rect, object setTarget = null, Action setAction = null, bool autoSet = false) @@ -387,10 +444,10 @@ namespace Explorer } else { - value = GUILayout.TextField(value.ToString(), new GUILayoutOption[] { GUILayout.MaxWidth(m_rect.width - 260) }); + value = GUILayout.TextField(value.ToString(), new GUILayoutOption[] { GUILayout.MaxWidth(m_rect.width - 260) }); } - if (autoSet || (allowSet && GUILayout.Button("Apply", new GUILayoutOption[] { GUILayout.Width(60) }))) + if (autoSet || (allowSet && GUILayout.Button("Apply", new GUILayoutOption[] { GUILayout.Width(60) }))) { setAction.Invoke(setTarget); } diff --git a/src_2018/WindowManager.cs b/src_2018/WindowManager.cs index 5878065..547b44a 100644 --- a/src_2018/WindowManager.cs +++ b/src_2018/WindowManager.cs @@ -142,11 +142,11 @@ namespace Explorer // ============= Resize Window Helper ============ - static readonly GUIContent gcDrag = new GUIContent("<->"); + //static readonly GUIContent gcDrag = new GUIContent("<->"); - private static bool isResizing = false; - private static Rect m_currentResize; - private static int m_currentWindow; + //private static bool isResizing = false; + //private static Rect m_currentResize; + //private static int m_currentWindow; public static Rect ResizeWindow(Rect _rect, int ID) {