From e175e9c43870bf52b07007f203eb433030b58817 Mon Sep 17 00:00:00 2001 From: sinaioutlander <49360850+sinaioutlander@users.noreply.github.com> Date: Thu, 5 Nov 2020 17:33:04 +1100 Subject: [PATCH] refactor --- src/{UI/Main => }/Console/AutoCompleter.cs | 10 +- src/{UI/Main => }/Console/CSharpLexer.cs | 4 +- src/{UI/Main => }/Console/CodeEditor.cs | 6 +- .../Main => }/Console/Lexer/CommentMatch.cs | 2 +- src/{UI/Main => }/Console/Lexer/InputLexer.cs | 2 +- .../Main => }/Console/Lexer/KeywordMatch.cs | 2 +- src/{UI/Main => }/Console/Lexer/Matcher.cs | 2 +- .../Main => }/Console/Lexer/NumberMatch.cs | 2 +- .../Main => }/Console/Lexer/StringMatch.cs | 2 +- .../Main => }/Console/Lexer/SymbolMatch.cs | 2 +- src/{UI/Main => }/Console/ScriptEvaluator.cs | 2 +- .../Main => }/Console/ScriptInteraction.cs | 5 +- src/{UI/Main => }/Console/Suggestion.cs | 3 +- src/ExplorerBepInPlugin.cs | 95 ++- src/ExplorerCore.cs | 2 +- src/Extensions/ReflectionExtensions.cs | 41 - src/Extensions/UnityExtensions.cs | 20 - src/Helpers/ReflectionHelpers.cs | 41 +- src/Helpers/Texture2DHelpers.cs | 2 +- src/Helpers/UnityHelpers.cs | 20 +- .../CacheObject/CacheEnumerated.cs | 0 .../CacheObject/CacheFactory.cs | 0 .../CacheObject/CacheField.cs | 0 .../CacheObject/CacheMember.cs | 0 .../CacheObject/CacheMethod.cs | 0 .../CacheObject/CacheObjectBase.cs | 0 .../CacheObject/CacheProperty.cs | 0 .../Inspectors/GameObjectInspector.cs | 800 +++++++++++++++--- src/{UI/Main => }/Inspectors/InspectorBase.cs | 13 +- .../Main => Inspectors}/InspectorManager.cs | 13 +- .../Main => }/Inspectors/InstanceInspector.cs | 2 +- .../Inspectors/ReflectionInspector.cs | 2 +- src/{UI/Main => Inspectors}/SceneExplorer.cs | 6 +- .../Main => }/Inspectors/StaticInspector.cs | 2 +- src/UI/InteractiveValue/InteractiveValue.cs | 2 +- src/UI/{Main => }/MainMenu.cs | 5 +- src/UI/{Main => PageModel}/ConsolePage.cs | 5 +- src/UI/{Main => PageModel}/DebugConsole.cs | 4 +- src/UI/{Main => PageModel}/HomePage.cs | 3 +- src/UI/{Main => PageModel}/OptionsPage.cs | 8 +- src/UI/{Main => PageModel}/SearchPage.cs | 8 +- src/UI/{Main => }/PanelDragger.cs | 2 +- src/UI/Shared/{Syntax.cs => SyntaxColors.cs} | 2 +- src/UI/UIFactory.cs | 2 + src/UI/UIManager.cs | 4 +- src/UnityExplorer.csproj | 76 +- src/Unstrip/Scene/SceneUnstrip.cs | 2 +- 47 files changed, 890 insertions(+), 336 deletions(-) rename src/{UI/Main => }/Console/AutoCompleter.cs (98%) rename src/{UI/Main => }/Console/CSharpLexer.cs (98%) rename src/{UI/Main => }/Console/CodeEditor.cs (99%) rename src/{UI/Main => }/Console/Lexer/CommentMatch.cs (97%) rename src/{UI/Main => }/Console/Lexer/InputLexer.cs (99%) rename src/{UI/Main => }/Console/Lexer/KeywordMatch.cs (98%) rename src/{UI/Main => }/Console/Lexer/Matcher.cs (94%) rename src/{UI/Main => }/Console/Lexer/NumberMatch.cs (95%) rename src/{UI/Main => }/Console/Lexer/StringMatch.cs (95%) rename src/{UI/Main => }/Console/Lexer/SymbolMatch.cs (98%) rename src/{UI/Main => }/Console/ScriptEvaluator.cs (98%) rename src/{UI/Main => }/Console/ScriptInteraction.cs (91%) rename src/{UI/Main => }/Console/Suggestion.cs (97%) delete mode 100644 src/Extensions/ReflectionExtensions.cs delete mode 100644 src/Extensions/UnityExtensions.cs rename src/{ => Inspectors}/CacheObject/CacheEnumerated.cs (100%) rename src/{ => Inspectors}/CacheObject/CacheFactory.cs (100%) rename src/{ => Inspectors}/CacheObject/CacheField.cs (100%) rename src/{ => Inspectors}/CacheObject/CacheMember.cs (100%) rename src/{ => Inspectors}/CacheObject/CacheMethod.cs (100%) rename src/{ => Inspectors}/CacheObject/CacheObjectBase.cs (100%) rename src/{ => Inspectors}/CacheObject/CacheProperty.cs (100%) rename src/{UI/Main => }/Inspectors/GameObjectInspector.cs (56%) rename src/{UI/Main => }/Inspectors/InspectorBase.cs (94%) rename src/{UI/Main => Inspectors}/InspectorManager.cs (95%) rename src/{UI/Main => }/Inspectors/InstanceInspector.cs (92%) rename src/{UI/Main => }/Inspectors/ReflectionInspector.cs (94%) rename src/{UI/Main => Inspectors}/SceneExplorer.cs (99%) rename src/{UI/Main => }/Inspectors/StaticInspector.cs (92%) rename src/UI/{Main => }/MainMenu.cs (98%) rename src/UI/{Main => PageModel}/ConsolePage.cs (99%) rename src/UI/{Main => PageModel}/DebugConsole.cs (99%) rename src/UI/{Main => PageModel}/HomePage.cs (95%) rename src/UI/{Main => PageModel}/OptionsPage.cs (61%) rename src/UI/{Main => PageModel}/SearchPage.cs (60%) rename src/UI/{Main => }/PanelDragger.cs (99%) rename src/UI/Shared/{Syntax.cs => SyntaxColors.cs} (95%) diff --git a/src/UI/Main/Console/AutoCompleter.cs b/src/Console/AutoCompleter.cs similarity index 98% rename from src/UI/Main/Console/AutoCompleter.cs rename to src/Console/AutoCompleter.cs index 05ebc21..902a3c0 100644 --- a/src/UI/Main/Console/AutoCompleter.cs +++ b/src/Console/AutoCompleter.cs @@ -4,10 +4,10 @@ using System.Linq; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.UI; -#if CPP -#endif +using UnityExplorer.UI; +using UnityExplorer.UI.PageModel; -namespace UnityExplorer.UI.Main.Console +namespace UnityExplorer.Console { public class AutoCompleter { @@ -17,7 +17,7 @@ namespace UnityExplorer.UI.Main.Console private const int UPDATES_PER_BATCH = 100; public static GameObject m_mainObj; - private static RectTransform m_thisRect; + //private static RectTransform m_thisRect; private static readonly List m_suggestionButtons = new List(); private static readonly List m_suggestionTexts = new List(); @@ -259,7 +259,7 @@ namespace UnityExplorer.UI.Main.Console m_mainObj = obj; var mainRect = obj.GetComponent(); - m_thisRect = mainRect; + //m_thisRect = mainRect; mainRect.pivot = new Vector2(0f, 1f); mainRect.anchorMin = new Vector2(0.45f, 0.45f); mainRect.anchorMax = new Vector2(0.65f, 0.6f); diff --git a/src/UI/Main/Console/CSharpLexer.cs b/src/Console/CSharpLexer.cs similarity index 98% rename from src/UI/Main/Console/CSharpLexer.cs rename to src/Console/CSharpLexer.cs index c820b47..96662f8 100644 --- a/src/UI/Main/Console/CSharpLexer.cs +++ b/src/Console/CSharpLexer.cs @@ -1,9 +1,9 @@ using System.Collections.Generic; using System.Text; -using UnityExplorer.UI.Main.Console.Lexer; +using UnityExplorer.Console.Lexer; using UnityEngine; -namespace UnityExplorer.UI.Main.Console +namespace UnityExplorer.Console { public static class CSharpLexer { diff --git a/src/UI/Main/Console/CodeEditor.cs b/src/Console/CodeEditor.cs similarity index 99% rename from src/UI/Main/Console/CodeEditor.cs rename to src/Console/CodeEditor.cs index 579e509..dcac903 100644 --- a/src/UI/Main/Console/CodeEditor.cs +++ b/src/Console/CodeEditor.cs @@ -2,13 +2,15 @@ using System.Linq; using System.Text; using UnityExplorer.Input; -using UnityExplorer.UI.Main.Console.Lexer; +using UnityExplorer.Console.Lexer; using TMPro; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.UI; +using UnityExplorer.UI; +using UnityExplorer.UI.PageModel; -namespace UnityExplorer.UI.Main.Console +namespace UnityExplorer.Console { public class CodeEditor { diff --git a/src/UI/Main/Console/Lexer/CommentMatch.cs b/src/Console/Lexer/CommentMatch.cs similarity index 97% rename from src/UI/Main/Console/Lexer/CommentMatch.cs rename to src/Console/Lexer/CommentMatch.cs index 7e38d19..e5f019c 100644 --- a/src/UI/Main/Console/Lexer/CommentMatch.cs +++ b/src/Console/Lexer/CommentMatch.cs @@ -1,7 +1,7 @@ using System.Collections.Generic; using UnityEngine; -namespace UnityExplorer.UI.Main.Console.Lexer +namespace UnityExplorer.Console.Lexer { public sealed class CommentMatch : Matcher { diff --git a/src/UI/Main/Console/Lexer/InputLexer.cs b/src/Console/Lexer/InputLexer.cs similarity index 99% rename from src/UI/Main/Console/Lexer/InputLexer.cs rename to src/Console/Lexer/InputLexer.cs index 10d3845..b329880 100644 --- a/src/UI/Main/Console/Lexer/InputLexer.cs +++ b/src/Console/Lexer/InputLexer.cs @@ -1,6 +1,6 @@ using System.Collections.Generic; -namespace UnityExplorer.UI.Main.Console.Lexer +namespace UnityExplorer.Console.Lexer { public struct LexerMatchInfo { diff --git a/src/UI/Main/Console/Lexer/KeywordMatch.cs b/src/Console/Lexer/KeywordMatch.cs similarity index 98% rename from src/UI/Main/Console/Lexer/KeywordMatch.cs rename to src/Console/Lexer/KeywordMatch.cs index dc6ceae..1a8e65a 100644 --- a/src/UI/Main/Console/Lexer/KeywordMatch.cs +++ b/src/Console/Lexer/KeywordMatch.cs @@ -1,7 +1,7 @@ using System.Collections.Generic; using UnityEngine; -namespace UnityExplorer.UI.Main.Console.Lexer +namespace UnityExplorer.Console.Lexer { public sealed class KeywordMatch : Matcher { diff --git a/src/UI/Main/Console/Lexer/Matcher.cs b/src/Console/Lexer/Matcher.cs similarity index 94% rename from src/UI/Main/Console/Lexer/Matcher.cs rename to src/Console/Lexer/Matcher.cs index 955f0bd..3cbaaa5 100644 --- a/src/UI/Main/Console/Lexer/Matcher.cs +++ b/src/Console/Lexer/Matcher.cs @@ -2,7 +2,7 @@ using UnityExplorer.Unstrip.ColorUtility; using UnityEngine; -namespace UnityExplorer.UI.Main.Console.Lexer +namespace UnityExplorer.Console.Lexer { public abstract class Matcher { diff --git a/src/UI/Main/Console/Lexer/NumberMatch.cs b/src/Console/Lexer/NumberMatch.cs similarity index 95% rename from src/UI/Main/Console/Lexer/NumberMatch.cs rename to src/Console/Lexer/NumberMatch.cs index a3efb9e..7ff3c4c 100644 --- a/src/UI/Main/Console/Lexer/NumberMatch.cs +++ b/src/Console/Lexer/NumberMatch.cs @@ -1,6 +1,6 @@ using UnityEngine; -namespace UnityExplorer.UI.Main.Console.Lexer +namespace UnityExplorer.Console.Lexer { public sealed class NumberMatch : Matcher { diff --git a/src/UI/Main/Console/Lexer/StringMatch.cs b/src/Console/Lexer/StringMatch.cs similarity index 95% rename from src/UI/Main/Console/Lexer/StringMatch.cs rename to src/Console/Lexer/StringMatch.cs index 4053d6f..33309e1 100644 --- a/src/UI/Main/Console/Lexer/StringMatch.cs +++ b/src/Console/Lexer/StringMatch.cs @@ -1,7 +1,7 @@ using System.Collections.Generic; using UnityEngine; -namespace UnityExplorer.UI.Main.Console.Lexer +namespace UnityExplorer.Console.Lexer { public sealed class StringMatch : Matcher { diff --git a/src/UI/Main/Console/Lexer/SymbolMatch.cs b/src/Console/Lexer/SymbolMatch.cs similarity index 98% rename from src/UI/Main/Console/Lexer/SymbolMatch.cs rename to src/Console/Lexer/SymbolMatch.cs index e9de316..8c0811b 100644 --- a/src/UI/Main/Console/Lexer/SymbolMatch.cs +++ b/src/Console/Lexer/SymbolMatch.cs @@ -2,7 +2,7 @@ using System.Linq; using UnityEngine; -namespace UnityExplorer.UI.Main.Console.Lexer +namespace UnityExplorer.Console.Lexer { public sealed class SymbolMatch : Matcher { diff --git a/src/UI/Main/Console/ScriptEvaluator.cs b/src/Console/ScriptEvaluator.cs similarity index 98% rename from src/UI/Main/Console/ScriptEvaluator.cs rename to src/Console/ScriptEvaluator.cs index 9784617..652a277 100644 --- a/src/UI/Main/Console/ScriptEvaluator.cs +++ b/src/Console/ScriptEvaluator.cs @@ -6,7 +6,7 @@ using Mono.CSharp; // Thanks to ManlyMarco for this -namespace UnityExplorer.UI.Main.Console +namespace UnityExplorer.Console { public class ScriptEvaluator : Evaluator, IDisposable { diff --git a/src/UI/Main/Console/ScriptInteraction.cs b/src/Console/ScriptInteraction.cs similarity index 91% rename from src/UI/Main/Console/ScriptInteraction.cs rename to src/Console/ScriptInteraction.cs index a80af9e..040d287 100644 --- a/src/UI/Main/Console/ScriptInteraction.cs +++ b/src/Console/ScriptInteraction.cs @@ -1,7 +1,10 @@ using System; using Mono.CSharp; +using UnityExplorer.UI; +using UnityExplorer.UI.PageModel; +using UnityExplorer.Inspectors; -namespace UnityExplorer.UI.Main.Console +namespace UnityExplorer.Console { public class ScriptInteraction : InteractiveBase { diff --git a/src/UI/Main/Console/Suggestion.cs b/src/Console/Suggestion.cs similarity index 97% rename from src/UI/Main/Console/Suggestion.cs rename to src/Console/Suggestion.cs index 7b9602c..eaa19f4 100644 --- a/src/UI/Main/Console/Suggestion.cs +++ b/src/Console/Suggestion.cs @@ -3,8 +3,9 @@ using System.Collections.Generic; using System.Linq; using System.Reflection; using UnityEngine; +using UnityExplorer.Helpers; -namespace UnityExplorer.UI.Main.Console +namespace UnityExplorer.Console { public struct Suggestion { diff --git a/src/ExplorerBepInPlugin.cs b/src/ExplorerBepInPlugin.cs index 0b03c96..61d4d52 100644 --- a/src/ExplorerBepInPlugin.cs +++ b/src/ExplorerBepInPlugin.cs @@ -7,6 +7,7 @@ using BepInEx.Logging; using HarmonyLib; using UnityEngine; using UnityEngine.SceneManagement; +using UnityEngine.UI; #if CPP using UnhollowerRuntimeLib; using BepInEx.IL2CPP; @@ -14,57 +15,25 @@ using BepInEx.IL2CPP; namespace UnityExplorer { +#if MONO [BepInPlugin(ExplorerCore.GUID, "UnityExplorer", ExplorerCore.VERSION)] -#if CPP - public class ExplorerBepInPlugin : BasePlugin -#else public class ExplorerBepInPlugin : BaseUnityPlugin -#endif { public static ExplorerBepInPlugin Instance; - public static ManualLogSource Logging => -#if CPP - Instance?.Log; -#else - Instance?.Logger; -#endif + public static ManualLogSource Logging => Instance?.Logger; public static readonly Harmony HarmonyInstance = new Harmony(ExplorerCore.GUID); -#if CPP - // temporary for Il2Cpp until scene change delegate works - private static string lastSceneName; -#endif - - // Init -#if CPP - public override void Load() - { -#else internal void Awake() { -#endif Instance = this; -#if CPP - ClassInjector.RegisterTypeInIl2Cpp(); - - var obj = new GameObject( - "ExplorerBehaviour", - new Il2CppSystem.Type[] - { - Il2CppType.Of() - } - ); - GameObject.DontDestroyOnLoad(obj); -#else SceneManager.activeSceneChanged += DoSceneChange; -#endif new ExplorerCore(); - // HarmonyInstance.PatchAll(); + HarmonyInstance.PatchAll(); } internal static void DoSceneChange(Scene arg0, Scene arg1) @@ -72,7 +41,54 @@ namespace UnityExplorer ExplorerCore.OnSceneChange(); } -#if CPP // BepInEx Il2Cpp mod class doesn't have monobehaviour methods yet, so wrap them in a dummy. + internal void Update() + { + ExplorerCore.Update(); + } + + } +#endif + +#if CPP + [BepInPlugin(ExplorerCore.GUID, "UnityExplorer", ExplorerCore.VERSION)] + public class ExplorerBepInPlugin : BasePlugin + { + public static ExplorerBepInPlugin Instance; + + public static ManualLogSource Logging => Instance?.Log; + + public static readonly Harmony HarmonyInstance = new Harmony(ExplorerCore.GUID); + + // temporary for Il2Cpp until scene change delegate works + private static string lastSceneName; + + // Init + public override void Load() + { + Instance = this; + + ClassInjector.RegisterTypeInIl2Cpp(); + + var obj = new GameObject( + "ExplorerBehaviour", + new Il2CppSystem.Type[] + { + Il2CppType.Of() + } + ); + GameObject.DontDestroyOnLoad(obj); + + new ExplorerCore(); + + HarmonyInstance.PatchAll(); + } + + internal static void DoSceneChange(Scene arg0, Scene arg1) + { + ExplorerCore.OnSceneChange(); + } + + // BepInEx Il2Cpp mod class doesn't have monobehaviour methods yet, so wrap them in a dummy. public class ExplorerBehaviour : MonoBehaviour { public ExplorerBehaviour(IntPtr ptr) : base(ptr) { } @@ -82,23 +98,20 @@ namespace UnityExplorer Logging.LogMessage("ExplorerBehaviour.Awake"); } -#endif internal void Update() { ExplorerCore.Update(); -#if CPP var scene = SceneManager.GetActiveScene(); if (scene.name != lastSceneName) { lastSceneName = scene.name; DoSceneChange(scene, scene); } -#endif + } -#if CPP } -#endif } +#endif } #endif diff --git a/src/ExplorerCore.cs b/src/ExplorerCore.cs index b9939c4..a8f9223 100644 --- a/src/ExplorerCore.cs +++ b/src/ExplorerCore.cs @@ -2,7 +2,7 @@ using UnityExplorer.Config; using UnityExplorer.Input; using UnityExplorer.UI; -using UnityExplorer.UI.Main; +using UnityExplorer.UI.PageModel; using UnityEngine; namespace UnityExplorer diff --git a/src/Extensions/ReflectionExtensions.cs b/src/Extensions/ReflectionExtensions.cs deleted file mode 100644 index 8e80eda..0000000 --- a/src/Extensions/ReflectionExtensions.cs +++ /dev/null @@ -1,41 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using UnityExplorer.Helpers; - -namespace UnityExplorer -{ - public static class ReflectionExtensions - { -#if CPP - public static object Il2CppCast(this object obj, Type castTo) - { - return ReflectionHelpers.Il2CppCast(obj, castTo); - } -#endif - - public static IEnumerable TryGetTypes(this Assembly asm) - { - try - { - return asm.GetTypes(); - } - catch (ReflectionTypeLoadException e) - { - try - { - return asm.GetExportedTypes(); - } - catch - { - return e.Types.Where(t => t != null); - } - } - catch - { - return Enumerable.Empty(); - } - } - } -} diff --git a/src/Extensions/UnityExtensions.cs b/src/Extensions/UnityExtensions.cs deleted file mode 100644 index bede877..0000000 --- a/src/Extensions/UnityExtensions.cs +++ /dev/null @@ -1,20 +0,0 @@ -using UnityEngine; - -namespace UnityExplorer -{ - public static class UnityExtensions - { - public static string GetTransformPath(this Transform t, bool includeThisName = false) - { - string path = includeThisName ? t.transform.name : ""; - - while (t.parent != null) - { - t = t.parent; - path = $"{t.name}/{path}"; - } - - return path; - } - } -} diff --git a/src/Helpers/ReflectionHelpers.cs b/src/Helpers/ReflectionHelpers.cs index 9a63832..a2dd7c8 100644 --- a/src/Helpers/ReflectionHelpers.cs +++ b/src/Helpers/ReflectionHelpers.cs @@ -2,6 +2,7 @@ using System.Collections; using System.Collections.Generic; using System.IO; +using System.Linq; using System.Reflection; using UnityEngine; using BF = System.Reflection.BindingFlags; @@ -16,7 +17,7 @@ using System.Runtime.InteropServices; namespace UnityExplorer.Helpers { [SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "External methods")] - public class ReflectionHelpers + public static class ReflectionHelpers { public static BF CommonFlags = BF.Public | BF.Instance | BF.NonPublic | BF.Static; @@ -37,7 +38,13 @@ namespace UnityExplorer.Helpers #if CPP private static readonly Dictionary ClassPointers = new Dictionary(); - public static object Il2CppCast(object obj, Type castTo) + [DllImport("GameAssembly", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public static extern bool il2cpp_class_is_assignable_from(IntPtr klass, IntPtr oklass); + + [DllImport("GameAssembly", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + public static extern IntPtr il2cpp_object_get_class(IntPtr obj); + + public static object Il2CppCast(this object obj, Type castTo) { if (!(obj is Il2CppSystem.Object ilObj)) { @@ -79,15 +86,31 @@ namespace UnityExplorer.Helpers return Activator.CreateInstance(castTo, ilObj.Pointer); } - - [DllImport("GameAssembly", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] - public static extern bool il2cpp_class_is_assignable_from(IntPtr klass, IntPtr oklass); - - [DllImport("GameAssembly", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] - public static extern IntPtr il2cpp_object_get_class(IntPtr obj); - #endif + public static IEnumerable TryGetTypes(this Assembly asm) + { + try + { + return asm.GetTypes(); + } + catch (ReflectionTypeLoadException e) + { + try + { + return asm.GetExportedTypes(); + } + catch + { + return e.Types.Where(t => t != null); + } + } + catch + { + return Enumerable.Empty(); + } + } + public static Type GetTypeByName(string fullName) { foreach (var asm in AppDomain.CurrentDomain.GetAssemblies()) diff --git a/src/Helpers/Texture2DHelpers.cs b/src/Helpers/Texture2DHelpers.cs index 7f49814..0cee478 100644 --- a/src/Helpers/Texture2DHelpers.cs +++ b/src/Helpers/Texture2DHelpers.cs @@ -53,7 +53,7 @@ namespace UnityExplorer.Helpers } } - public static Texture2D Copy(Texture2D orig, Rect rect, bool isDTXnmNormal = false) + public static Texture2D Copy(Texture2D orig, Rect rect) //, bool isDTXnmNormal = false) { Color[] pixels; diff --git a/src/Helpers/UnityHelpers.cs b/src/Helpers/UnityHelpers.cs index d0928e0..8adc6e6 100644 --- a/src/Helpers/UnityHelpers.cs +++ b/src/Helpers/UnityHelpers.cs @@ -2,7 +2,7 @@ namespace UnityExplorer.Helpers { - public class UnityHelpers + public static class UnityHelpers { private static Camera m_mainCamera; @@ -25,5 +25,23 @@ namespace UnityExplorer.Helpers return UnityEngine.SceneManagement.SceneManager.GetActiveScene().name; } } + + public static string ToStringLong(this Vector3 vec) + { + return $"X: {vec.x:F3}, Y: {vec.y:F3}, Z: {vec.z:F3}"; + } + + public static string GetTransformPath(this Transform t, bool includeThisName = false) + { + string path = includeThisName ? t.transform.name : ""; + + while (t.parent != null) + { + t = t.parent; + path = $"{t.name}/{path}"; + } + + return path; + } } } diff --git a/src/CacheObject/CacheEnumerated.cs b/src/Inspectors/CacheObject/CacheEnumerated.cs similarity index 100% rename from src/CacheObject/CacheEnumerated.cs rename to src/Inspectors/CacheObject/CacheEnumerated.cs diff --git a/src/CacheObject/CacheFactory.cs b/src/Inspectors/CacheObject/CacheFactory.cs similarity index 100% rename from src/CacheObject/CacheFactory.cs rename to src/Inspectors/CacheObject/CacheFactory.cs diff --git a/src/CacheObject/CacheField.cs b/src/Inspectors/CacheObject/CacheField.cs similarity index 100% rename from src/CacheObject/CacheField.cs rename to src/Inspectors/CacheObject/CacheField.cs diff --git a/src/CacheObject/CacheMember.cs b/src/Inspectors/CacheObject/CacheMember.cs similarity index 100% rename from src/CacheObject/CacheMember.cs rename to src/Inspectors/CacheObject/CacheMember.cs diff --git a/src/CacheObject/CacheMethod.cs b/src/Inspectors/CacheObject/CacheMethod.cs similarity index 100% rename from src/CacheObject/CacheMethod.cs rename to src/Inspectors/CacheObject/CacheMethod.cs diff --git a/src/CacheObject/CacheObjectBase.cs b/src/Inspectors/CacheObject/CacheObjectBase.cs similarity index 100% rename from src/CacheObject/CacheObjectBase.cs rename to src/Inspectors/CacheObject/CacheObjectBase.cs diff --git a/src/CacheObject/CacheProperty.cs b/src/Inspectors/CacheObject/CacheProperty.cs similarity index 100% rename from src/CacheObject/CacheProperty.cs rename to src/Inspectors/CacheObject/CacheProperty.cs diff --git a/src/UI/Main/Inspectors/GameObjectInspector.cs b/src/Inspectors/GameObjectInspector.cs similarity index 56% rename from src/UI/Main/Inspectors/GameObjectInspector.cs rename to src/Inspectors/GameObjectInspector.cs index 2a628cf..4a4b9bb 100644 --- a/src/UI/Main/Inspectors/GameObjectInspector.cs +++ b/src/Inspectors/GameObjectInspector.cs @@ -2,24 +2,23 @@ using System.Collections.Generic; using System.Linq; using UnityExplorer.Helpers; +using UnityExplorer.UI; using UnityExplorer.UI.Shared; using UnityExplorer.Unstrip.ColorUtility; +using UnityExplorer.Unstrip.LayerMasks; using TMPro; using UnityEngine; using UnityEngine.UI; -using UnityExplorer.Unstrip.LayerMasks; +using UnityExplorer.Input; -namespace UnityExplorer.UI.Main.Inspectors +namespace UnityExplorer.Inspectors { - // TODO: - // fix path and name input for very long input (use content size fitter + preffered size + vert layout group) - // make back button (inspect parent button) - // make controls panel (transform controls, set parent, etc) - public class GameObjectInspector : InspectorBase { public override string TabLabel => $" [G] {TargetGO?.name}"; + public static GameObjectInspector ActiveInstance { get; private set; } + // just to help with casting in il2cpp public GameObject TargetGO; @@ -27,14 +26,17 @@ namespace UnityExplorer.UI.Main.Inspectors private static bool m_UIConstructed; - private static GameObject m_content; + private static GameObject s_content; public override GameObject Content { - get => m_content; - set => m_content = value; + get => s_content; + set => s_content = value; } // cached ui elements + private static ScrollRect s_contentScroll; + private static float s_lastScrollPos; + public static TMP_InputField m_nameInput; private static string m_lastName; public static TMP_InputField m_pathInput; @@ -69,8 +71,26 @@ namespace UnityExplorer.UI.Main.Inspectors private static int s_lastCompCount; public static readonly List s_compToggles = new List(); + // gameobject controls inputs + private static TMP_InputField s_setParentInput; + + private static ControlEditor s_positionControl; + private static ControlEditor s_localPosControl; + private static ControlEditor s_rotationControl; + private static ControlEditor s_scaleControl; + + internal struct ControlEditor + { + public TMP_InputField fullValue; + public Slider[] sliders; + public TMP_InputField[] inputs; + public Text[] values; + } + public GameObjectInspector(GameObject target) : base(target) { + ActiveInstance = this; + TargetGO = target; if (!TargetGO) @@ -87,22 +107,52 @@ namespace UnityExplorer.UI.Main.Inspectors } } + public override void SetContentActive() + { + base.SetContentActive(); + ActiveInstance = this; + } + + public override void SetContentInactive() + { + base.SetContentInactive(); + ActiveInstance = null; + } + public override void Update() { base.Update(); - if (m_pendingDestroy || InspectorManager.Instance.m_activeInspector != this) - { + if (m_pendingDestroy || ActiveInstance != this) return; - } + + if (!s_sliderChangedWanted) + s_lastScrollPos = s_contentScroll.verticalScrollbar.value; RefreshTopInfo(); RefreshChildObjectList(); RefreshComponentList(); + + RefreshControls(); + + if (s_sliderChangedWanted) + { + UpdateSliderControl(); + } } + private void ChangeInspectorTarget(GameObject newTarget) + { + if (!newTarget) + return; + + this.Target = this.TargetGO = newTarget; + } + +#region TOP INFO + private void RefreshTopInfo() { if (m_lastName != TargetGO.name) @@ -153,6 +203,38 @@ namespace UnityExplorer.UI.Main.Inspectors } } + private static void OnApplyNameClicked() + { + if (ActiveInstance == null) return; + + ActiveInstance.TargetGO.name = m_nameInput.text; + } + + private static void OnEnableToggled(bool enabled) + { + if (ActiveInstance == null) return; + + ActiveInstance.TargetGO.SetActive(enabled); + } + + private static void OnLayerSelected(int layer) + { + if (ActiveInstance == null) return; + + ActiveInstance.TargetGO.layer = layer; + } + + private static void OnCompToggleClicked(int index, bool value) + { + var comp = s_compShortlist[index]; + + (comp as Behaviour).enabled = value; + } + +#endregion + +#region CHILD LIST + private void RefreshChildObjectList() { s_allChildren = new GameObject[TargetGO.transform.childCount]; @@ -223,6 +305,38 @@ namespace UnityExplorer.UI.Main.Inspectors s_lastChildCount = newCount; } + private static void OnChildListObjectClicked(int index) + { + if (!(InspectorManager.Instance.m_activeInspector is GameObjectInspector instance)) return; + + if (index >= s_childrenShortlist.Count || !s_childrenShortlist[index]) + { + return; + } + + instance.ChangeInspectorTarget(s_childrenShortlist[index]); + + instance.Update(); + } + + private static void OnBackButtonClicked() + { + if (!(InspectorManager.Instance.m_activeInspector is GameObjectInspector instance)) return; + + instance.ChangeInspectorTarget(instance.TargetGO.transform.parent.gameObject); + } + + private static void OnChildListPageTurn() + { + if (!(InspectorManager.Instance.m_activeInspector is GameObjectInspector instance)) return; + + instance.RefreshChildObjectList(); + } + +#endregion + +#region COMPONENT LIST + private void RefreshComponentList() { s_allComps = TargetGO.GetComponents().ToArray(); @@ -296,76 +410,6 @@ namespace UnityExplorer.UI.Main.Inspectors s_lastCompCount = newCount; } - private void ChangeInspectorTarget(GameObject newTarget) - { - if (!newTarget) - return; - - this.Target = this.TargetGO = newTarget; - } - - private static void ApplyNameClicked() - { - if (!(InspectorManager.Instance.m_activeInspector is GameObjectInspector instance)) return; - - instance.TargetGO.name = m_nameInput.text; - } - - private static void OnEnableToggled(bool enabled) - { - if (!(InspectorManager.Instance.m_activeInspector is GameObjectInspector instance)) return; - - instance.TargetGO.SetActive(enabled); - } - - private static void OnLayerSelected(int layer) - { - if (!(InspectorManager.Instance.m_activeInspector is GameObjectInspector instance)) return; - - instance.TargetGO.layer = layer; - } - - private static void OnCompToggleClicked(int index, bool value) - { - var comp = s_compShortlist[index]; - - (comp as Behaviour).enabled = value; - } - - #region CHILD LIST - - private static void OnChildListObjectClicked(int index) - { - if (!(InspectorManager.Instance.m_activeInspector is GameObjectInspector instance)) return; - - if (index >= s_childrenShortlist.Count || !s_childrenShortlist[index]) - { - return; - } - - instance.ChangeInspectorTarget(s_childrenShortlist[index]); - - instance.Update(); - } - - private static void OnBackButtonClicked() - { - if (!(InspectorManager.Instance.m_activeInspector is GameObjectInspector instance)) return; - - instance.ChangeInspectorTarget(instance.TargetGO.transform.parent.gameObject); - } - - private static void OnChildListPageTurn() - { - if (!(InspectorManager.Instance.m_activeInspector is GameObjectInspector instance)) return; - - instance.RefreshChildObjectList(); - } - - #endregion - - #region COMPONENT LIST - private static void OnCompListObjectClicked(int index) { if (index >= s_compShortlist.Count || !s_compShortlist[index]) @@ -383,15 +427,215 @@ namespace UnityExplorer.UI.Main.Inspectors instance.RefreshComponentList(); } - #endregion +#endregion - #region UI CONSTRUCTION +#region TRANSFORM CONTROLS + + private void RefreshControls() + { + s_positionControl.fullValue.text = TargetGO.transform.position.ToStringLong(); + s_positionControl.values[0].text = TargetGO.transform.position.x.ToString("F3"); + s_positionControl.values[1].text = TargetGO.transform.position.y.ToString("F3"); + s_positionControl.values[2].text = TargetGO.transform.position.z.ToString("F3"); + + s_localPosControl.fullValue.text = TargetGO.transform.localPosition.ToStringLong(); + s_localPosControl.values[0].text = TargetGO.transform.position.x.ToString("F3"); + s_localPosControl.values[1].text = TargetGO.transform.position.y.ToString("F3"); + s_localPosControl.values[2].text = TargetGO.transform.position.z.ToString("F3"); + + s_rotationControl.fullValue.text = TargetGO.transform.eulerAngles.ToStringLong(); + s_rotationControl.values[0].text = TargetGO.transform.position.x.ToString("F3"); + s_rotationControl.values[1].text = TargetGO.transform.position.y.ToString("F3"); + s_rotationControl.values[2].text = TargetGO.transform.position.z.ToString("F3"); + + s_scaleControl.fullValue.text = TargetGO.transform.localScale.ToStringLong(); + s_scaleControl.values[0].text = TargetGO.transform.position.x.ToString("F3"); + s_scaleControl.values[1].text = TargetGO.transform.position.y.ToString("F3"); + s_scaleControl.values[2].text = TargetGO.transform.position.z.ToString("F3"); + + } + + private static void OnSetParentClicked() + { + var input = s_setParentInput.text; + + ExplorerCore.Log("Todo set parent to '" + input + "'"); + } + + internal enum ControlType + { + position, + localPosition, + eulerAngles, + localScale + } + + internal enum VectorValue + { + x, y, z + }; + + private static bool s_sliderChangedWanted; + private static Slider s_currentSlider; + private static ControlType s_currentSliderType; + private static VectorValue s_currentSliderValueType; + private static float s_currentSliderValue; + + private static void OnSliderControlChanged(float value, Slider slider, ControlType controlType, VectorValue vectorValue) + { + if (value == 0) + s_sliderChangedWanted = false; + else + { + if (!s_sliderChangedWanted) + { + s_sliderChangedWanted = true; + s_currentSlider = slider; + s_currentSliderType = controlType; + s_currentSliderValueType = vectorValue; + //ExplorerCore.LogWarning("Starting slide with scroll value of " + s_lastScrollPos); + } + + s_currentSliderValue = value; + } + } + + private static void UpdateSliderControl() + { + //s_contentScroll.verticalNormalizedPosition = s_lastScrollPos; + ////s_contentScroll.verticalScrollbar.value = s_lastScrollPos; + //ExplorerCore.Log("Set scroll pos to " + s_lastScrollPos); + + if (!InputManager.GetMouseButton(0)) + { + s_sliderChangedWanted = false; + s_currentSlider.value = 0; + + return; + } + + if (ActiveInstance == null) return; + + var transform = ActiveInstance.TargetGO.transform; + + // get the current vector for the control type + Vector3 vector = Vector2.zero; + switch (s_currentSliderType) + { + case ControlType.position: + vector = transform.position; break; + case ControlType.localPosition: + vector = transform.localPosition; break; + case ControlType.eulerAngles: + vector = transform.eulerAngles; break; + case ControlType.localScale: + vector = transform.localScale; break; + } + + // apply vector value change + switch (s_currentSliderValueType) + { + case VectorValue.x: + vector.x += s_currentSliderValue; break; + case VectorValue.y: + vector.y += s_currentSliderValue; break; + case VectorValue.z: + vector.z += s_currentSliderValue; break; + } + + // set vector to transform member + switch (s_currentSliderType) + { + case ControlType.position: + transform.position = vector; break; + case ControlType.localPosition: + transform.localPosition = vector; break; + case ControlType.eulerAngles: + transform.eulerAngles = vector; break; + case ControlType.localScale: + transform.localScale = vector; break; + } + } + + private static void OnVectorControlInputApplied(ControlType controlType, VectorValue vectorValue) + { + if (!(InspectorManager.Instance.m_activeInspector is GameObjectInspector instance)) return; + + // get relevant input for controltype + value + + TMP_InputField[] inputs = null; + switch (controlType) + { + case ControlType.position: + inputs = s_positionControl.inputs; break; + case ControlType.localPosition: + inputs = s_localPosControl.inputs; break; + case ControlType.eulerAngles: + inputs = s_rotationControl.inputs; break; + case ControlType.localScale: + inputs = s_scaleControl.inputs; break; + } + TMP_InputField input = inputs[(int)vectorValue]; + + float val = float.Parse(input.text); + + // apply transform value + + Vector3 vector = Vector3.zero; + var transform = instance.TargetGO.transform; + switch (controlType) + { + case ControlType.position: + vector = transform.position; break; + case ControlType.localPosition: + vector = transform.localPosition; break; + case ControlType.eulerAngles: + vector = transform.eulerAngles; break; + case ControlType.localScale: + vector = transform.localScale; break; + } + + switch (vectorValue) + { + case VectorValue.x: + vector.x = val; break; + case VectorValue.y: + vector.y = val; break; + case VectorValue.z: + vector.z = val; break; + } + + // set back to transform + switch (controlType) + { + case ControlType.position: + transform.position = vector; break; + case ControlType.localPosition: + transform.localPosition = vector; break; + case ControlType.eulerAngles: + transform.eulerAngles = vector; break; + case ControlType.localScale: + transform.localScale = vector; break; + } + } + +#endregion + +#region UI CONSTRUCTION private void ConstructUI() { var parent = InspectorManager.Instance.m_inspectorContent; - m_content = UIFactory.CreateScrollView(parent, out GameObject scrollContent, new Color(0.1f, 0.1f, 0.1f)); + s_content = UIFactory.CreateScrollView(parent, out GameObject scrollContent, new Color(0.1f, 0.1f, 0.1f)); + s_contentScroll = s_content.GetComponent(); + //s_contentScroll.onValueChanged.AddListener((Vector2 val) => + //{ + // if (s_sliderChangedWanted) + // { + // s_contentScroll.verticalNormalizedPosition = s_lastScrollPos; + // } + //}); var scrollGroup = scrollContent.GetComponent(); scrollGroup.childForceExpandHeight = false; @@ -400,21 +644,26 @@ namespace UnityExplorer.UI.Main.Inspectors ConstructTopArea(scrollContent); - var midGroupObj = UIFactory.CreateHorizontalGroup(scrollContent, new Color(1,1,1,0)); - var midGroup = midGroupObj.GetComponent(); - midGroup.spacing = 5; - midGroup.childForceExpandWidth = true; - midGroup.childControlWidth = true; - var midlayout = midGroupObj.AddComponent(); - midlayout.minHeight = 40; - midlayout.flexibleHeight = 10000; - midlayout.flexibleWidth = 25000; - midlayout.minWidth = 200; - - ConstructChildList(midGroupObj); - ConstructCompList(midGroupObj); - ConstructControls(scrollContent); + + // not sure if i'll use this mid group... + + //var midGroupObj = UIFactory.CreateHorizontalGroup(scrollContent, new Color(1,1,1,0)); + //var midGroup = midGroupObj.GetComponent(); + //midGroup.spacing = 5; + //midGroup.childForceExpandWidth = true; + //midGroup.childControlWidth = true; + //midGroup.childForceExpandHeight = true; + //midGroup.childControlHeight = false; + //var midlayout = midGroupObj.AddComponent(); + //midlayout.minHeight = 40; + //midlayout.flexibleHeight = 10000; + //midlayout.flexibleWidth = 25000; + //midlayout.minWidth = 200; + + ConstructChildList(scrollContent); + + ConstructCompList(scrollContent); } private void ConstructTopArea(GameObject scrollContent) @@ -439,7 +688,7 @@ namespace UnityExplorer.UI.Main.Inspectors #if CPP backButton.onClick.AddListener(new Action(OnBackButtonClicked)); #else - backButton.onClick.AddListener(OnBackButtonClicked()); + backButton.onClick.AddListener(OnBackButtonClicked); #endif var backText = backButtonObj.GetComponentInChildren(); backText.text = "<"; @@ -517,7 +766,7 @@ namespace UnityExplorer.UI.Main.Inspectors #if CPP applyNameBtn.onClick.AddListener(new Action(() => { ApplyNameClicked(); })); #else - applyNameBtn.onClick.AddListener(() => { ApplyNameClicked(); }); + applyNameBtn.onClick.AddListener(() => { OnApplyNameClicked(); }); #endif var applyNameText = applyNameBtnObj.GetComponentInChildren(); applyNameText.text = "Apply"; @@ -559,7 +808,7 @@ namespace UnityExplorer.UI.Main.Inspectors sceneLayerGroup.childControlWidth = true; sceneLayerGroup.spacing = 5; - var layerLabel = UIFactory.CreateLabel(sceneLayerRow, TextAnchor. MiddleCenter); + var layerLabel = UIFactory.CreateLabel(sceneLayerRow, TextAnchor.MiddleCenter); var layerText = layerLabel.GetComponent(); layerText.text = "Layer:"; layerText.fontSize = 14; @@ -607,7 +856,7 @@ namespace UnityExplorer.UI.Main.Inspectors private void ConstructChildList(GameObject parent) { - var vertGroupObj = UIFactory.CreateVerticalGroup(parent, new Color(1,1,1,0)); + var vertGroupObj = UIFactory.CreateVerticalGroup(parent, new Color(1, 1, 1, 0)); var vertGroup = vertGroupObj.GetComponent(); vertGroup.childForceExpandHeight = false; vertGroup.childForceExpandWidth = false; @@ -615,6 +864,9 @@ namespace UnityExplorer.UI.Main.Inspectors var vertLayout = vertGroupObj.AddComponent(); vertLayout.minWidth = 120; vertLayout.flexibleWidth = 25000; + vertLayout.minHeight = 150; + vertLayout.flexibleHeight = 5000; + vertLayout.preferredHeight = 250; var childTitleObj = UIFactory.CreateLabel(vertGroupObj, TextAnchor.MiddleLeft); var childTitleText = childTitleObj.GetComponent(); @@ -624,6 +876,10 @@ namespace UnityExplorer.UI.Main.Inspectors var childTitleLayout = childTitleObj.AddComponent(); childTitleLayout.minHeight = 30; + s_childListPageHandler = new PageHandler(); + s_childListPageHandler.ConstructUI(vertGroupObj); + s_childListPageHandler.OnPageChanged += OnChildListPageTurn; + var childrenScrollObj = UIFactory.CreateScrollView(vertGroupObj, out s_childListContent, new Color(0.07f, 0.07f, 0.07f)); var contentLayout = childrenScrollObj.AddComponent(); contentLayout.minHeight = 50; @@ -638,10 +894,6 @@ namespace UnityExplorer.UI.Main.Inspectors var childGroup = s_childListContent.GetComponent(); childGroup.childControlHeight = true; childGroup.spacing = 2; - - s_childListPageHandler = new PageHandler(); - s_childListPageHandler.ConstructUI(vertGroupObj); - s_childListPageHandler.OnPageChanged += OnChildListPageTurn; } private void AddChildListButton() @@ -693,6 +945,9 @@ namespace UnityExplorer.UI.Main.Inspectors var vertLayout = vertGroupObj.AddComponent(); vertLayout.minWidth = 120; vertLayout.flexibleWidth = 25000; + vertLayout.minHeight = 150; + vertLayout.flexibleHeight = 5000; + vertLayout.preferredHeight = 250; var compTitleObj = UIFactory.CreateLabel(vertGroupObj, TextAnchor.MiddleLeft); var compTitleText = compTitleObj.GetComponent(); @@ -702,6 +957,10 @@ namespace UnityExplorer.UI.Main.Inspectors var childTitleLayout = compTitleObj.AddComponent(); childTitleLayout.minHeight = 30; + s_compListPageHandler = new PageHandler(); + s_compListPageHandler.ConstructUI(vertGroupObj); + s_compListPageHandler.OnPageChanged += OnCompListPageTurn; + var compScrollObj = UIFactory.CreateScrollView(vertGroupObj, out s_compListContent, new Color(0.07f, 0.07f, 0.07f)); var contentLayout = compScrollObj.AddComponent(); contentLayout.minHeight = 50; @@ -716,10 +975,6 @@ namespace UnityExplorer.UI.Main.Inspectors var scrollRect = compScrollObj.GetComponentInChildren(); scrollRect.horizontalScrollbar = null; - - s_compListPageHandler = new PageHandler(); - s_compListPageHandler.ConstructUI(vertGroupObj); - s_compListPageHandler.OnPageChanged += OnCompListPageTurn; } private void AddCompListButton() @@ -739,6 +994,8 @@ namespace UnityExplorer.UI.Main.Inspectors btnLayout.flexibleHeight = 0; btnGroupObj.AddComponent(); + // Behaviour enabled toggle + var toggleObj = UIFactory.CreateToggle(btnGroupObj, out Toggle toggle, out Text toggleText); var togBg = toggleObj.transform.Find("Background").GetComponent(); togBg.color = new Color(0.1f, 0.1f, 0.1f, 1); @@ -747,6 +1004,9 @@ namespace UnityExplorer.UI.Main.Inspectors toggleLayout.flexibleWidth = 0; toggleLayout.minHeight = 25; toggleLayout.flexibleHeight = 0; + var checkImg = toggleObj.transform.Find("Background/Checkmark").GetComponent(); + checkImg.color = SyntaxColors.Class_Instance.ToColor(); + checkImg.color *= 0.66f; #if CPP toggle.onValueChanged.AddListener(new Action((bool val) => { OnCompToggleClicked(thisIndex, val); })); #else @@ -755,6 +1015,8 @@ namespace UnityExplorer.UI.Main.Inspectors toggleText.text = ""; s_compToggles.Add(toggle); + // Main component button + GameObject mainButtonObj = UIFactory.CreateButton(btnGroupObj); LayoutElement mainBtnLayout = mainButtonObj.AddComponent(); mainBtnLayout.minHeight = 25; @@ -772,27 +1034,31 @@ namespace UnityExplorer.UI.Main.Inspectors mainBtn.onClick.AddListener(() => { OnCompListObjectClicked(thisIndex); }); #endif + // Component button text + Text mainText = mainButtonObj.GetComponentInChildren(); mainText.alignment = TextAnchor.MiddleLeft; mainText.horizontalOverflow = HorizontalWrapMode.Overflow; - mainText.color = Syntax.Class_Instance.ToColor(); + mainText.color = SyntaxColors.Class_Instance.ToColor(); s_compListTexts.Add(mainText); + + // TODO remove component button } - private const int CONTROLS_MAX_HEIGHT = 220; + //private const int CONTROLS_MIN_HEIGHT = 220; - private void ConstructControls(GameObject scrollContent) + private void ConstructControls(GameObject parent) { - var controlsObj = UIFactory.CreateVerticalGroup(scrollContent, new Color(0.07f, 0.07f, 0.07f)); + var controlsObj = UIFactory.CreateVerticalGroup(parent, new Color(0.07f, 0.07f, 0.07f)); var controlsGroup = controlsObj.GetComponent(); controlsGroup.childForceExpandWidth = false; controlsGroup.childControlWidth = true; controlsGroup.childForceExpandHeight = false; - var controlsLayout = controlsObj.AddComponent(); - controlsLayout.minHeight = CONTROLS_MAX_HEIGHT; - controlsLayout.flexibleHeight = 0; - controlsLayout.minWidth = 250; - controlsLayout.flexibleWidth = 9000; + controlsGroup.spacing = 5; + controlsGroup.padding.top = 4; + controlsGroup.padding.left = 4; + controlsGroup.padding.right = 4; + controlsGroup.padding.bottom = 4; // ~~~~~~ Top row ~~~~~~ @@ -806,13 +1072,46 @@ namespace UnityExplorer.UI.Main.Inspectors var hideButtonObj = UIFactory.CreateButton(topRow); var hideButton = hideButtonObj.GetComponent