浏览代码
(Refactor) Advanced Hierarchy View (#12)
(Refactor) Advanced Hierarchy View (#12)
* Base Rename * Added Preferences / Contextual Visibility * Updated Changelog * Added Attributes for registering Icons * Added All/None/Invert Toggles in preferences/main
GitHub
5 年前
当前提交
54ee3a0b
共有 22 个文件被更改,包括 421 次插入 和 0 次删除
-
6CHANGELOG.md
-
2Runtime/Ingredients/Counter/Counter.cs
-
1Runtime/Ingredients/Factory/Factory.cs
-
1Runtime/Ingredients/Interactions/Interactive.cs
-
1Runtime/Ingredients/StateMachine/State.cs
-
1Runtime/Ingredients/StateMachine/StateMachine.cs
-
1Runtime/Ingredients/Timer/Timer.cs
-
1Runtime/LevelScripting/Events/OnEnableDisableEvent.cs
-
1Runtime/LevelScripting/Events/OnMessageEvent.cs
-
1Runtime/LevelScripting/Events/OnStartEvent.cs
-
1Runtime/LevelScripting/Events/OnTriggerEvent.cs
-
18Runtime/Attributes/AdvancedHierarchyIconAttribute.cs
-
11Runtime/Attributes/AdvancedHierarchyIconAttribute.cs.meta
-
124Editor/AdvancedHierarchyView/AdvancedHierarchyPreferences.cs
-
11Editor/AdvancedHierarchyView/AdvancedHierarchyPreferences.cs.meta
-
240Editor/AdvancedHierarchyView/AdvancedHierarchyView.cs
-
0/Editor/AdvancedHierarchyView.meta
-
0/Runtime/Attributes.meta
-
0/Runtime/Attributes
-
0/Editor/AdvancedHierarchyView/AdvancedHierarchyView.cs.meta
|
|||
using System; |
|||
using System.Collections; |
|||
using System.Collections.Generic; |
|||
using UnityEngine; |
|||
|
|||
namespace GameplayIngredients |
|||
{ |
|||
[AttributeUsage(AttributeTargets.Class)] |
|||
public class AdvancedHierarchyIconAttribute : Attribute |
|||
{ |
|||
public readonly string icon; |
|||
|
|||
public AdvancedHierarchyIconAttribute(string icon) |
|||
{ |
|||
this.icon = icon; |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 84a5d6b8a98d866468c7f3773aed6138 |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
using System.Collections; |
|||
using System.Collections.Generic; |
|||
using UnityEngine; |
|||
using UnityEditor; |
|||
using System; |
|||
using System.Linq; |
|||
|
|||
namespace GameplayIngredients.Editor |
|||
{ |
|||
static class AdvancedHierarchyPreferences |
|||
{ |
|||
[SettingsProvider] |
|||
public static SettingsProvider GetAdvancedHierarchyPreferences() |
|||
{ |
|||
var provider = new SettingsProvider("Preferences/Gameplay Ingredients/Advanced Hierarchy View", SettingsScope.User) |
|||
{ |
|||
label = "Advanced Hierarchy Options", |
|||
guiHandler = OnGUI |
|||
}; |
|||
return provider; |
|||
} |
|||
|
|||
static Dictionary<Type, bool> s_CachedVisibility; |
|||
static readonly string componentPrefix = "GameplayIngredients.HierarchyHints."; |
|||
static readonly string staticPref = "GameplayIngredients.HierarchyHints.Static"; |
|||
|
|||
[InitializeOnLoadMethod] |
|||
static void Initialize() |
|||
{ |
|||
if (s_CachedVisibility == null) |
|||
s_CachedVisibility = new Dictionary<Type, bool>(); |
|||
|
|||
foreach (var type in AdvancedHierarchyView.allTypes) |
|||
{ |
|||
if (!s_CachedVisibility.ContainsKey(type)) |
|||
s_CachedVisibility.Add(type, EditorPrefs.GetBool(componentPrefix + type.Name, true)); |
|||
else |
|||
s_CachedVisibility[type] = EditorPrefs.GetBool(componentPrefix + type.Name, true); |
|||
} |
|||
} |
|||
|
|||
public static bool showStatic { get { return EditorPrefs.GetBool(staticPref, true); } } |
|||
|
|||
public static bool IsVisible(Type t) |
|||
{ |
|||
if (s_CachedVisibility.ContainsKey(t)) |
|||
return s_CachedVisibility[t]; |
|||
else |
|||
return false; |
|||
} |
|||
|
|||
static void OnGUI(string search) |
|||
{ |
|||
EditorGUIUtility.labelWidth = 260; |
|||
EditorGUI.indentLevel ++; |
|||
EditorGUILayout.Space(); |
|||
EditorGUILayout.LabelField("Preferences", EditorStyles.boldLabel); |
|||
EditorGUI.indentLevel++; |
|||
EditorGUI.BeginChangeCheck(); |
|||
var s = EditorGUILayout.Toggle("Show Static", showStatic); |
|||
if(EditorGUI.EndChangeCheck()) |
|||
{ |
|||
EditorPrefs.SetBool(staticPref, s); |
|||
EditorApplication.RepaintHierarchyWindow(); |
|||
} |
|||
EditorGUI.indentLevel--; |
|||
EditorGUILayout.Space(); |
|||
using (new GUILayout.HorizontalScope()) |
|||
{ |
|||
|
|||
GUILayout.Label("Visible Components", EditorStyles.boldLabel, GUILayout.Width(EditorGUIUtility.labelWidth)); |
|||
if (GUILayout.Button("All")) |
|||
ToggleAll(true); |
|||
if (GUILayout.Button("None")) |
|||
ToggleAll(false); |
|||
if (GUILayout.Button("Invert")) |
|||
ToggleInvert(); |
|||
} |
|||
|
|||
EditorGUI.indentLevel ++; |
|||
foreach (var type in AdvancedHierarchyView.allTypes) |
|||
{ |
|||
EditorGUI.BeginChangeCheck(); |
|||
var value = EditorGUILayout.Toggle(type.Name, s_CachedVisibility[type]); |
|||
if(EditorGUI.EndChangeCheck()) |
|||
{ |
|||
SetValue(type, value, true); |
|||
} |
|||
} |
|||
EditorGUI.indentLevel -= 2; |
|||
} |
|||
|
|||
static void SetValue(Type type, bool value, bool repaint = false) |
|||
{ |
|||
s_CachedVisibility[type] = value; |
|||
EditorPrefs.SetBool(componentPrefix + type.Name, value); |
|||
if(repaint) |
|||
EditorApplication.RepaintHierarchyWindow(); |
|||
|
|||
} |
|||
|
|||
static void ToggleAll(bool value) |
|||
{ |
|||
var allTypes = s_CachedVisibility.Keys.ToArray(); |
|||
foreach(var type in allTypes) |
|||
{ |
|||
SetValue(type, value); |
|||
} |
|||
EditorApplication.RepaintHierarchyWindow(); |
|||
} |
|||
|
|||
static void ToggleInvert() |
|||
{ |
|||
var allTypes = s_CachedVisibility.Keys.ToArray(); |
|||
foreach (var type in allTypes) |
|||
{ |
|||
SetValue(type, !s_CachedVisibility[type]); |
|||
} |
|||
EditorApplication.RepaintHierarchyWindow(); |
|||
} |
|||
|
|||
} |
|||
|
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 64b05588573cd7d4dbd975642cd735a5 |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
using System; |
|||
using System.Collections.Generic; |
|||
using UnityEngine; |
|||
using UnityEngine.UI; |
|||
using UnityEngine.VFX; |
|||
using UnityEditor; |
|||
using GameplayIngredients.StateMachines; |
|||
using UnityEngine.Playables; |
|||
using System.Linq; |
|||
using System.Reflection; |
|||
|
|||
namespace GameplayIngredients.Editor |
|||
{ |
|||
[InitializeOnLoad] |
|||
public static class AdvancedHierarchyView |
|||
{ |
|||
const string kMenuPath = "Edit/Advanced Hierarchy View %."; |
|||
public const int kMenuPriority = 230; |
|||
|
|||
[MenuItem(kMenuPath, priority = kMenuPriority, validate = false)] |
|||
static void Toggle() |
|||
{ |
|||
if (Active) |
|||
Active = false; |
|||
else |
|||
Active = true; |
|||
} |
|||
|
|||
[MenuItem(kMenuPath, priority = kMenuPriority, validate = true)] |
|||
static bool ToggleCheck() |
|||
{ |
|||
Menu.SetChecked(kMenuPath, Active); |
|||
return SceneView.sceneViews.Count > 0; |
|||
} |
|||
|
|||
static readonly string kPreferenceName = "GameplayIngredients.HierarchyHints"; |
|||
public static bool Active |
|||
{ |
|||
get |
|||
{ |
|||
return EditorPrefs.GetBool(kPreferenceName, false); |
|||
} |
|||
|
|||
set |
|||
{ |
|||
EditorPrefs.SetBool(kPreferenceName, value); |
|||
UnityEditorInternal.InternalEditorUtility.RepaintAllViews(); |
|||
} |
|||
} |
|||
|
|||
static AdvancedHierarchyView() |
|||
{ |
|||
EditorApplication.hierarchyWindowItemOnGUI -= HierarchyOnGUI; |
|||
EditorApplication.hierarchyWindowItemOnGUI += HierarchyOnGUI; |
|||
InitializeTypes(); |
|||
} |
|||
|
|||
static void InitializeTypes() |
|||
{ |
|||
RegisterComponentType( typeof(MonoBehaviour), "cs Script Icon"); |
|||
RegisterComponentType( typeof(Camera), "Camera Icon"); |
|||
RegisterComponentType( typeof(MeshRenderer), "MeshRenderer Icon"); |
|||
RegisterComponentType( typeof(SkinnedMeshRenderer), "SkinnedMeshRenderer Icon"); |
|||
RegisterComponentType( typeof(BoxCollider), "BoxCollider Icon"); |
|||
RegisterComponentType( typeof(SphereCollider), "SphereCollider Icon"); |
|||
RegisterComponentType( typeof(CapsuleCollider), "CapsuleCollider Icon"); |
|||
RegisterComponentType( typeof(MeshCollider), "MeshCollider Icon"); |
|||
RegisterComponentType( typeof(AudioSource), "AudioSource Icon"); |
|||
RegisterComponentType( typeof(Animation), "Animation Icon"); |
|||
RegisterComponentType( typeof(Animator), "Animator Icon"); |
|||
RegisterComponentType( typeof(PlayableDirector), "PlayableDirector Icon"); |
|||
RegisterComponentType( typeof(Light), "Light Icon"); |
|||
RegisterComponentType( typeof(LightProbeGroup), "LightProbeGroup Icon"); |
|||
RegisterComponentType( typeof(LightProbeProxyVolume), "LightProbeProxyVolume Icon"); |
|||
RegisterComponentType( typeof(ReflectionProbe), "ReflectionProbe Icon"); |
|||
RegisterComponentType( typeof(VisualEffect), "VisualEffect Icon"); |
|||
RegisterComponentType( typeof(ParticleSystem), "ParticleSystem Icon"); |
|||
RegisterComponentType( typeof(Canvas), "Canvas Icon"); |
|||
RegisterComponentType( typeof(Image), "Image Icon"); |
|||
RegisterComponentType( typeof(Text), "Text Icon"); |
|||
RegisterComponentType( typeof(Button), "Button Icon"); |
|||
RegisterComponentType( typeof(Folder), "Folder Icon"); |
|||
|
|||
foreach(var assembly in AppDomain.CurrentDomain.GetAssemblies()) |
|||
{ |
|||
try |
|||
{ |
|||
var types = assembly.GetTypes(); |
|||
foreach(var type in types) |
|||
{ |
|||
if(type.IsSubclassOf(typeof(MonoBehaviour)) && !type.IsAbstract) |
|||
{ |
|||
var attrib = type.GetCustomAttribute<AdvancedHierarchyIconAttribute>(); |
|||
if(attrib != null) |
|||
{ |
|||
RegisterComponentType(type, attrib.icon); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
catch(Exception e) |
|||
{ |
|||
Debug.LogWarning("Could not load types from assembly:" + assembly.FullName); |
|||
} |
|||
} |
|||
} |
|||
|
|||
public static void RegisterComponentType(Type t, string iconName) |
|||
{ |
|||
if (s_Definitions == null) |
|||
s_Definitions = new Dictionary<Type, string>(); |
|||
|
|||
if (!s_Definitions.ContainsKey(t)) |
|||
s_Definitions.Add(t, iconName); |
|||
} |
|||
|
|||
public static IEnumerable<Type> allTypes { get { return s_Definitions.Keys; } } |
|||
static Dictionary<Type, string> s_Definitions = new Dictionary<Type, string>(); |
|||
|
|||
static void HierarchyOnGUI(int instanceID, Rect selectionRect) |
|||
{ |
|||
if (!Active) return; |
|||
|
|||
var fullRect = selectionRect; |
|||
fullRect.xMin = 32; |
|||
fullRect.xMax = EditorGUIUtility.currentViewWidth; |
|||
GameObject o = EditorUtility.InstanceIDToObject(instanceID) as GameObject; |
|||
if (o == null) return; |
|||
|
|||
var c = GUI.color; |
|||
|
|||
bool isFolder = o.GetComponent<Folder>() != null; |
|||
|
|||
if(isFolder) |
|||
{ |
|||
fullRect.xMin += 28 + 14 * GetObjectDepth(o.transform); |
|||
fullRect.width = 16; |
|||
|
|||
EditorGUI.DrawRect(fullRect, EditorGUIUtility.isProSkin? Styles.proBackground : Styles.personalBackground); |
|||
DrawIcon(fullRect, Contents.GetContent(typeof(Folder)), o.GetComponent<Folder>().Color); |
|||
} |
|||
else |
|||
{ |
|||
if (o.isStatic && AdvancedHierarchyPreferences.showStatic) |
|||
{ |
|||
GUI.Label(fullRect, " S"); |
|||
EditorGUI.DrawRect(fullRect, Colors.dimGray); |
|||
} |
|||
|
|||
foreach (var type in s_Definitions.Keys) |
|||
{ |
|||
if(AdvancedHierarchyPreferences.IsVisible(type) && o.GetComponents(type).Length > 0) |
|||
selectionRect = DrawIcon(selectionRect, Contents.GetContent(type), Color.white); |
|||
} |
|||
} |
|||
GUI.color = c; |
|||
} |
|||
|
|||
static int GetObjectDepth(Transform t, int depth=0) |
|||
{ |
|||
if (t.parent == null) |
|||
return depth; |
|||
else |
|||
return GetObjectDepth(t.parent, depth + 1); |
|||
} |
|||
|
|||
|
|||
static Rect DrawIcon(Rect rect, GUIContent content, Color color, int size = 16) |
|||
{ |
|||
GUI.color = color; |
|||
GUI.Label(rect, content, Styles.icon); |
|||
rect.width = rect.width - size; |
|||
return rect; |
|||
} |
|||
|
|||
static class Contents |
|||
{ |
|||
static Dictionary<Type, GUIContent> s_Icons = new Dictionary<Type, GUIContent>(); |
|||
|
|||
public static void AddIcon(Type type, string IconName) |
|||
{ |
|||
GUIContent icon; |
|||
|
|||
Texture texture = AssetDatabase.LoadAssetAtPath<Texture>(IconName); |
|||
|
|||
if (texture == null) |
|||
icon = EditorGUIUtility.IconContent(IconName); |
|||
else |
|||
icon = new GUIContent(texture); |
|||
|
|||
s_Icons.Add(type, icon); |
|||
} |
|||
|
|||
public static GUIContent GetContent(Type t) |
|||
{ |
|||
if (!s_Icons.ContainsKey(t) && s_Definitions.ContainsKey(t)) |
|||
AddIcon(t,s_Definitions[t]); |
|||
|
|||
return s_Icons[t]; |
|||
} |
|||
} |
|||
|
|||
static class Colors |
|||
{ |
|||
public static Color orange = new Color(1.0f, 0.7f, 0.1f); |
|||
public static Color red = new Color(1.0f, 0.4f, 0.3f); |
|||
public static Color yellow = new Color(0.8f, 1.0f, 0.1f); |
|||
public static Color green = new Color(0.2f, 1.0f, 0.1f); |
|||
public static Color blue = new Color(0.5f, 0.8f, 1.0f); |
|||
public static Color violet = new Color(0.8f, 0.5f, 1.0f); |
|||
public static Color purple = new Color(1.0f, 0.5f, 0.8f); |
|||
public static Color dimGray = new Color(0.4f, 0.4f, 0.4f, 0.2f); |
|||
} |
|||
|
|||
static class Styles |
|||
{ |
|||
public static GUIStyle rightLabel; |
|||
public static GUIStyle icon; |
|||
|
|||
public static Color proBackground = new Color(0.25f, 0.25f, 0.25f, 1.0f); |
|||
public static Color personalBackground = new Color(0.75f, 0.75f, 0.75f, 1.0f); |
|||
|
|||
static Styles() |
|||
{ |
|||
rightLabel = new GUIStyle(EditorStyles.label); |
|||
rightLabel.alignment = TextAnchor.MiddleRight; |
|||
rightLabel.normal.textColor = Color.white; |
|||
rightLabel.onNormal.textColor = Color.white; |
|||
|
|||
rightLabel.active.textColor = Color.white; |
|||
rightLabel.onActive.textColor = Color.white; |
|||
|
|||
icon = new GUIStyle(rightLabel); |
|||
icon.padding = new RectOffset(); |
|||
icon.margin = new RectOffset(); |
|||
} |
|||
} |
|||
|
|||
} |
|||
} |
撰写
预览
正在加载...
取消
保存
Reference in new issue