123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286 |
- using System;
- using System.Linq;
- using UnityEditor;
- using UnityEngine;
- using Object = UnityEngine.Object;
- namespace EnhancedHierarchy {
- public static partial class Reflected {
- private static bool gameObjectStylesTypeLoaded = false;
- private static Type gameObjectTreeViewStylesType;
- private static readonly Type hierarchyWindowType = ReflectionHelper.FindType("UnityEditor.SceneHierarchyWindow");
- private static EditorWindow hierarchyWindowInstance;
- public static bool HierarchyFocused {
- get {
- return EditorWindow.focusedWindow && EditorWindow.focusedWindow.GetType() == hierarchyWindowType;
- }
- }
- public static Color PlaymodeTint {
- get {
- try {
- return !EditorApplication.isPlayingOrWillChangePlaymode ?
- Color.white :
- ReflectionHelper.FindType("UnityEditor.HostView").GetStaticField<object>("kPlayModeDarken").GetInstanceProperty<Color>("Color");
- } catch (Exception e) {
- if (Preferences.DebugEnabled)
- Debug.LogException(e);
- return Color.white;
- }
- }
- }
- public static EditorWindow HierarchyWindowInstance {
- get {
- if (hierarchyWindowInstance)
- return hierarchyWindowInstance;
- var lastHierarchy = (EditorWindow)null;
- try {
- lastHierarchy = hierarchyWindowType.GetStaticField<EditorWindow>("s_LastInteractedHierarchy");
- } catch (Exception e) {
- if (Preferences.DebugEnabled)
- Debug.LogException(e);
- }
- return lastHierarchy != null ?
- (hierarchyWindowInstance = lastHierarchy) :
- (hierarchyWindowInstance = (EditorWindow)Resources.FindObjectsOfTypeAll(hierarchyWindowType).FirstOrDefault());
- }
- }
- public static void ShowIconSelector(Object[] targetObjs, Rect activatorRect, bool showLabelIcons) {
- using(ProfilerSample.Get())
- try {
- var iconSelectorType = ReflectionHelper.FindType("UnityEditor.IconSelector");
- if (iconSelectorType.HasMethod<Object[], Rect, bool>("ShowAtPosition")) {
- if (!iconSelectorType.InvokeStaticMethod<bool, Object[], Rect, bool>("ShowAtPosition", targetObjs, activatorRect, showLabelIcons))
- Debug.LogWarning("Failed to open icon selector");
- return;
- } else {
- var instance = ScriptableObject.CreateInstance(iconSelectorType);
- if (instance.HasMethod<Object[], Rect, bool>("Init"))
- instance.InvokeMethod("Init", targetObjs, activatorRect, showLabelIcons);
- else {
- var affectedObj = targetObjs.FirstOrDefault();
- instance.InvokeMethod("Init", affectedObj, activatorRect, showLabelIcons);
- After.Condition(() => !instance, () => {
- var icon = GetObjectIcon(affectedObj);
- foreach (var obj in targetObjs)
- SetObjectIcon(obj, icon);
- });
- }
- }
- } catch (Exception e) {
- Debug.LogWarning("Failed to open icon selector\n" + e);
- }
- }
- public static void SetObjectIcon(Object obj, Texture2D texture) {
- using(ProfilerSample.Get()) {
- typeof(EditorGUIUtility).InvokeStaticMethod("SetIconForObject", obj, texture);
- EditorUtility.SetDirty(obj);
- }
- }
- public static Texture2D GetObjectIcon(Object obj) {
- using(ProfilerSample.Get())
- return typeof(EditorGUIUtility).InvokeStaticMethod<Texture2D, Object>("GetIconForObject", obj);
- }
- public static bool GetTransformIsExpanded(GameObject go) {
- using(ProfilerSample.Get())
- try {
- var data = TreeView.GetInstanceProperty<object>("data");
- var isExpanded = data.InvokeMethod<bool, int>("IsExpanded", go.GetInstanceID());
- return isExpanded;
- } catch (Exception e) {
- Preferences.NumericChildExpand.Value = false;
- Debug.LogException(e);
- Debug.LogWarningFormat("Disabled \"{0}\" because it failed to get hierarchy info", Preferences.NumericChildExpand.Label.text);
- return false;
- }
- }
- public static void SetHierarchySelectionNeedSync() {
- using(ProfilerSample.Get())
- try {
- if (HierarchyWindowInstance)
- SceneHierarchyOrWindow.SetInstanceProperty("selectionSyncNeeded", true);
- } catch (Exception e) {
- Debug.LogWarningFormat("Enabling \"{0}\" because it caused an exception", Preferences.AllowSelectingLockedObjects.Label.text);
- Debug.LogException(e);
- Preferences.AllowSelectingLockedObjects.Value = true;
- }
- }
- private static object SceneHierarchy { get { return HierarchyWindowInstance.GetInstanceProperty<object>("sceneHierarchy"); } }
- private static object SceneHierarchyOrWindow {
- get {
- #if UNITY_2018_3_OR_NEWER
- return HierarchyWindowInstance.GetInstanceProperty<object>("sceneHierarchy");
- #else
- return HierarchyWindowInstance;
- #endif
- }
- }
- public static object TreeView { get { return SceneHierarchyOrWindow.GetInstanceProperty<object>("treeView"); } }
- public static object TreeViewGUI { get { return TreeView.GetInstanceProperty<object>("gui"); } }
- public static bool IconWidthSupported {
- get {
- #if UNITY_2018_3_OR_NEWER
- return TreeView != null && TreeViewGUI != null && TreeViewGUI.HasField("k_IconWidth");
- #else
- return false;
- #endif
- }
- }
- // Icon to the left side of obj name, introducted on Unity 2018.3
- public static float IconWidth {
- get {
- if (!IconWidthSupported)
- return 0;
- return TreeViewGUI.GetInstanceField<float>("k_IconWidth");
- }
- set { TreeViewGUI.SetInstanceField("k_IconWidth", value); }
- }
- public static class HierarchyArea {
- static HierarchyArea() {
- if (Preferences.DebugEnabled && !Supported)
- Debug.LogWarning("HierarchyArea not supported!");
- }
- public static bool Supported {
- get {
- try {
- return HierarchyWindowInstance != null && TreeView != null && TreeViewGUI != null;
- } catch {
- return false;
- }
- }
- }
- public static float IndentWidth {
- get { return TreeViewGUI.GetInstanceField<float>("k_IndentWidth"); }
- set { TreeViewGUI.SetInstanceField("k_IndentWidth", value); }
- }
- //public static float foldoutYOffset {
- // get { return TreeViewGUI.GetFieldValue<float>("foldoutYOffset"); }
- // set { TreeViewGUI.SetFieldValue("foldoutYOffset", value); }
- //}
- private static float baseIndentDefault = float.NaN;
- public static float BaseIndent {
- get {
- var val = TreeViewGUI.GetInstanceField<float>("k_BaseIndent");
- if (float.IsNaN(baseIndentDefault))
- baseIndentDefault = val;
- return val;
- }
- set {
- if (float.IsNaN(baseIndentDefault))
- baseIndentDefault = BaseIndent;
- TreeViewGUI.SetInstanceField("k_BaseIndent", baseIndentDefault + value);
- }
- }
- public static float BottomRowMargin {
- get { return TreeViewGUI.GetInstanceField<float>("k_BottomRowMargin"); }
- set { TreeViewGUI.SetInstanceField("k_BottomRowMargin", value); }
- }
- public static float TopRowMargin {
- get { return TreeViewGUI.GetInstanceField<float>("k_TopRowMargin"); }
- set { TreeViewGUI.SetInstanceField("k_TopRowMargin", value); }
- }
- public static float HalfDropBetweenHeight {
- get { return TreeViewGUI.GetInstanceField<float>("k_HalfDropBetweenHeight"); }
- set { TreeViewGUI.SetInstanceField("k_HalfDropBetweenHeight", value); }
- }
- public static float IconWidth {
- get { return TreeViewGUI.GetInstanceField<float>("k_IconWidth"); }
- set { TreeViewGUI.SetInstanceField("k_IconWidth", value); }
- }
- public static float LineHeight {
- get { return TreeViewGUI.GetInstanceField<float>("k_LineHeight"); }
- set { TreeViewGUI.SetInstanceField("k_LineHeight", value); }
- }
- public static float SpaceBetweenIconAndText {
- get { return TreeViewGUI.GetInstanceField<float>("k_SpaceBetweenIconAndText"); }
- set { TreeViewGUI.SetInstanceField("k_SpaceBetweenIconAndText", value); }
- }
- public static float IconLeftPadding {
- get { return TreeViewGUI.GetInstanceProperty<float>("iconLeftPadding"); }
- set { TreeViewGUI.SetInstanceProperty("iconLeftPadding", value); }
- }
- public static float IconRightPadding { //Same as iconLeftPadding
- get { return TreeViewGUI.GetInstanceProperty<float>("iconRightPadding"); }
- set { TreeViewGUI.SetInstanceProperty("iconRightPadding", value); }
- }
- }
- private static Type GameObjectTreeViewStylesType {
- get {
- if (!gameObjectStylesTypeLoaded) {
- gameObjectStylesTypeLoaded = true;
- gameObjectTreeViewStylesType = TreeViewGUI.GetType().GetNestedType("GameObjectStyles", ReflectionHelper.FULL_BINDING);
- }
- return gameObjectTreeViewStylesType;
- }
- }
- public static bool NativeHierarchyHoverTintSupported {
- get {
- return GameObjectTreeViewStylesType != null && GameObjectTreeViewStylesType.HasField("hoveredBackgroundColor");
- }
- }
- // I implement the hover tint and then a few weeks later
- // unity implements it as a native feature
- public static Color NativeHierarchyHoverTint {
- get {
- if (Preferences.DebugEnabled && !NativeHierarchyHoverTintSupported) {
- Debug.LogWarning("Native hover tint not supported!");
- return Color.clear;
- }
- return GameObjectTreeViewStylesType.GetStaticField<Color>("hoveredBackgroundColor");
- }
- set {
- if (Preferences.DebugEnabled && !NativeHierarchyHoverTintSupported) {
- Debug.LogWarning("Native hover tint not supported!");
- return;
- }
- GameObjectTreeViewStylesType.SetStaticField("hoveredBackgroundColor", value);
- }
- }
- }
- }
|