├── .gitignore ├── EditorIconViewer.cs ├── InspectorButton.cs └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | [Ll]ibrary/ 2 | [Tt]emp/ 3 | [Oo]bj/ 4 | 5 | # Autogenerated VS/MD solution and project files 6 | *.csproj 7 | *.unityproj 8 | *.sln 9 | -------------------------------------------------------------------------------- /EditorIconViewer.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using UnityEditor; 3 | using System.Collections; 4 | using System.Linq; 5 | using System.Collections.Generic; 6 | 7 | public class EditorIconViewer : EditorWindow 8 | { 9 | public class IconGroup 10 | { 11 | public string name; 12 | public GUIStyle[] iconData; 13 | public float iconWidthThreshold; 14 | public float maxWidth; 15 | } 16 | 17 | // Icons are categorized by their height, into buckets defined by 18 | // the two arrays below. The number of thresholds should always exceed 19 | // the number of group names by one. 20 | public List iconGroups; 21 | public static float[] kIconThresholds = { 0, 9, 25, 35, 100, 99999 }; 22 | public static string[] kIconGroupNames = { "Mini", "Small", "Medium", "Large", "X-Large" }; 23 | 24 | #region Blacklisted Items 25 | // Names of known style states that have a texture present in the 'background' field but 26 | // whose icons show up as empty images when renderered. 27 | protected static bool kHideBlacklistedIcons = true; 28 | protected static HashSet kIconBlacklist = new HashSet() 29 | { 30 | "PlayerSettingsPlatform", 31 | "PreferencesSection", 32 | "ProfilerPaneLeftBackground", 33 | "flow var 0", 34 | "flow var 0 on", 35 | "flow var 1", 36 | "flow var 1 on", 37 | "flow var 2", 38 | "flow var 2 on", 39 | "flow var 3", 40 | "flow var 3 on", 41 | "flow var 4", 42 | "flow var 4 on", 43 | "flow var 5", 44 | "flow var 5 on", 45 | "flow var 6", 46 | "flow var 6 on", 47 | }; 48 | #endregion 49 | 50 | public static float kSidePanelMinWidth = 150; 51 | public static float kSidePanelMaxWidth = 250; 52 | public static float kScrollbarWidth = 15; 53 | public static float kSelectionGridPadding = 10; 54 | 55 | public static string kUsageString = 56 | "All of the icons presented in this collection are easily accessible when writing a custom editor script, for both Inspectors and Editor Windows. " + 57 | "In the OnEnable method of your editor, obtain a copy of the editor's skin with the following:\n\n" + 58 | "GUISkin _editorSkin = EditorGUIUtility.GetBuiltinSkin(EditorSkin.Inspector);\n\n" + 59 | "Textures shown in this tool can be retrieved by using their style names, shown at the top of the left-hand panel when you select an icon from the grid. For example:\n\n" + 60 | "GUILayout.Button(_editorSkin.GetStyle(\"MeTransPlayhead\").normal.background);\n\n" + 61 | "Or you can simply use the style itself when rendering a control:\n\n" + 62 | "GUILayout.Button(\"\", _editorSkin.GetStyle(\"MeTransPlayhead\"));\n\n" + 63 | "If additional style states are available (such as Focused, Hover, or Active), they will appear in the panel when selected."; 64 | 65 | protected GUISkin _editorSkin; 66 | protected GUIStyle _selectedIcon; 67 | protected Vector2 _scrollPos; 68 | protected float _drawScale; 69 | 70 | [MenuItem("Tools/Editor Icons")] 71 | static void Init() 72 | { 73 | EditorIconViewer window = (EditorIconViewer)GetWindow(typeof(EditorIconViewer), false, "Editor Icon Viewer"); 74 | window.position = new Rect(150, 150, 700, 400); 75 | } 76 | 77 | void OnEnable() 78 | { 79 | _editorSkin = EditorGUIUtility.GetBuiltinSkin(EditorSkin.Inspector); 80 | _scrollPos = Vector2.zero; 81 | SetSelectedIcon(null); 82 | 83 | iconGroups = new List(); 84 | 85 | for (int i = 0; i < kIconGroupNames.Length; ++i) 86 | { 87 | IconGroup group = new IconGroup(); 88 | group.name = kIconGroupNames[i]; 89 | 90 | float minHeight = kIconThresholds[i]; 91 | float maxHeight = kIconThresholds[i + 1]; 92 | 93 | group.iconData = _editorSkin.customStyles 94 | .Where(style => 95 | { 96 | if (style.normal.background == null) 97 | return false; 98 | if (style.normal.background.height <= minHeight || style.normal.background.height > maxHeight) 99 | return false; 100 | if (kHideBlacklistedIcons && kIconBlacklist.Contains(style.name)) 101 | return false; 102 | 103 | return true; 104 | }) 105 | .OrderBy(style => style.normal.background.height).ToArray(); 106 | 107 | float maxWidth = 0; 108 | foreach (GUIStyle style in group.iconData) 109 | maxWidth = (style.normal.background.width > maxWidth) ? style.normal.background.width : maxWidth; 110 | group.maxWidth = maxWidth; 111 | 112 | iconGroups.Add(group); 113 | } 114 | } 115 | 116 | void OnGUI() 117 | { 118 | float sidePanelWidth = CalculateSidePanelWidth(); 119 | GUILayout.BeginArea(new Rect(0, 0, sidePanelWidth, position.height), GUI.skin.box); 120 | DrawIconDisplay(_selectedIcon); 121 | GUILayout.EndArea(); 122 | 123 | GUI.BeginGroup(new Rect(sidePanelWidth, 0, position.width - sidePanelWidth, position.height)); 124 | _scrollPos = GUILayout.BeginScrollView(_scrollPos, true, true, GUILayout.MaxWidth(position.width - sidePanelWidth)); 125 | 126 | for (int i = 0; i < iconGroups.Count; ++i) 127 | { 128 | IconGroup group = iconGroups[i]; 129 | EditorGUILayout.LabelField(group.name); 130 | DrawIconSelectionGrid(group.iconData, group.maxWidth); 131 | 132 | GUILayout.Space(15); 133 | } 134 | 135 | GUILayout.EndScrollView(); 136 | GUI.EndGroup(); 137 | } 138 | 139 | protected float CalculateSidePanelWidth() 140 | { 141 | return Mathf.Clamp(position.width * 0.21f, kSidePanelMinWidth, kSidePanelMaxWidth); 142 | } 143 | 144 | protected void DrawIconDisplay(GUIStyle style) 145 | { 146 | if (style == null) 147 | { 148 | DrawCenteredMessage("No icon selected"); 149 | GUILayout.FlexibleSpace(); 150 | DrawHelpIcon(); 151 | return; 152 | } 153 | 154 | Texture2D iconTexture = style.normal.background; 155 | 156 | EditorGUILayout.BeginVertical(); 157 | 158 | EditorGUILayout.BeginHorizontal(); 159 | GUILayout.FlexibleSpace(); 160 | GUILayout.Label(style.name, EditorStyles.whiteLargeLabel); 161 | GUILayout.FlexibleSpace(); 162 | EditorGUILayout.EndHorizontal(); 163 | 164 | EditorGUILayout.BeginHorizontal(); 165 | GUILayout.FlexibleSpace(); 166 | GUILayout.Label("Normal"); 167 | GUILayout.FlexibleSpace(); 168 | EditorGUILayout.EndHorizontal(); 169 | 170 | float iconOffset = 45; 171 | float iconWidth = iconTexture.width * _drawScale; 172 | float iconHeight = iconTexture.height * _drawScale; 173 | float sidePanelWidth = CalculateSidePanelWidth(); 174 | GUI.DrawTexture(new Rect((sidePanelWidth - iconWidth) * 0.5f, iconOffset, iconWidth, iconHeight), iconTexture, ScaleMode.StretchToFill); 175 | GUILayout.Space(iconHeight + 10); 176 | 177 | EditorGUILayout.BeginHorizontal(); 178 | if (GUILayout.Toggle(_drawScale == 1.0f, "1x", EditorStyles.miniButtonLeft)) 179 | { 180 | _drawScale = 1.0f; 181 | } 182 | if (GUILayout.Toggle(_drawScale == 1.5f, "1.5x", EditorStyles.miniButtonMid)) 183 | { 184 | _drawScale = 1.5f; 185 | } 186 | if (GUILayout.Toggle(_drawScale == 2.0f, "2x", EditorStyles.miniButtonRight)) 187 | { 188 | _drawScale = 2.0f; 189 | } 190 | EditorGUILayout.EndHorizontal(); 191 | 192 | GUILayout.Space(10); 193 | 194 | DrawIconStyleState(style.active, "Active"); 195 | DrawIconStyleState(style.hover, "Hover"); 196 | DrawIconStyleState(style.focused, "Focused"); 197 | 198 | GUILayout.Space(10); 199 | 200 | EditorGUILayout.LabelField(string.Format("Width: {0}px", iconTexture.width)); 201 | EditorGUILayout.LabelField(string.Format("Height: {0}px", iconTexture.height)); 202 | 203 | GUILayout.FlexibleSpace(); 204 | DrawHelpIcon(); 205 | 206 | EditorGUILayout.EndVertical(); 207 | } 208 | 209 | protected void DrawIconStyleState(GUIStyleState state, string label) 210 | { 211 | if (state == null || state.background == null) 212 | return; 213 | 214 | EditorGUILayout.BeginHorizontal(); 215 | GUILayout.FlexibleSpace(); 216 | GUILayout.Label(label); 217 | GUILayout.FlexibleSpace(); 218 | EditorGUILayout.EndHorizontal(); 219 | 220 | EditorGUILayout.BeginHorizontal(); 221 | GUILayout.FlexibleSpace(); 222 | GUILayout.Box(state.background); 223 | GUILayout.FlexibleSpace(); 224 | EditorGUILayout.EndHorizontal(); 225 | } 226 | 227 | protected void SetSelectedIcon(GUIStyle icon) 228 | { 229 | _selectedIcon = icon; 230 | _drawScale = 1.0f; 231 | } 232 | 233 | protected void DrawIconSelectionGrid(GUIStyle[] icons, float maxIconWidth) 234 | { 235 | float sidePanelWidth = CalculateSidePanelWidth(); 236 | int xCount = Mathf.FloorToInt((position.width - sidePanelWidth - kScrollbarWidth) / (maxIconWidth + kSelectionGridPadding)); 237 | int selected = GUILayout.SelectionGrid(-1, icons.Select(style => style.normal.background).ToArray(), xCount, GUI.skin.box); 238 | 239 | if (selected > -1) 240 | { 241 | SetSelectedIcon(icons[selected]); 242 | } 243 | } 244 | 245 | protected void DrawCenteredMessage(string msg) 246 | { 247 | EditorGUILayout.BeginHorizontal(); 248 | GUILayout.FlexibleSpace(); 249 | EditorGUILayout.BeginVertical(); 250 | GUILayout.FlexibleSpace(); 251 | GUILayout.Label(msg); 252 | GUILayout.FlexibleSpace(); 253 | EditorGUILayout.EndVertical(); 254 | GUILayout.FlexibleSpace(); 255 | EditorGUILayout.EndHorizontal(); 256 | } 257 | 258 | protected void DrawHelpIcon() 259 | { 260 | EditorGUILayout.BeginHorizontal(); 261 | GUILayout.FlexibleSpace(); 262 | if (GUILayout.Button("", _editorSkin.GetStyle("CN EntryInfo"))) 263 | { 264 | EditorUtility.DisplayDialog("Editor Icon Viewer", kUsageString, "Ok"); 265 | } 266 | EditorGUILayout.EndHorizontal(); 267 | } 268 | } 269 | -------------------------------------------------------------------------------- /InspectorButton.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | #if UNITY_EDITOR 3 | using UnityEditor; 4 | #endif 5 | using System.Reflection; 6 | 7 | /// 8 | /// This attribute can only be applied to fields because its 9 | /// associated PropertyDrawer only operates on fields (either 10 | /// public or tagged with the [SerializeField] attribute) in 11 | /// the target MonoBehaviour. 12 | /// 13 | [System.AttributeUsage(System.AttributeTargets.Field)] 14 | public class InspectorButtonAttribute : PropertyAttribute 15 | { 16 | public static float kDefaultButtonWidth = 80; 17 | 18 | public readonly string MethodName; 19 | 20 | private float _buttonWidth = kDefaultButtonWidth; 21 | public float ButtonWidth 22 | { 23 | get { return _buttonWidth; } 24 | set { _buttonWidth = value; } 25 | } 26 | 27 | public InspectorButtonAttribute(string MethodName) 28 | { 29 | this.MethodName = MethodName; 30 | } 31 | } 32 | 33 | #if UNITY_EDITOR 34 | [CustomPropertyDrawer(typeof(InspectorButtonAttribute))] 35 | public class InspectorButtonPropertyDrawer : PropertyDrawer 36 | { 37 | private MethodInfo _eventMethodInfo = null; 38 | 39 | public override void OnGUI(Rect position, SerializedProperty prop, GUIContent label) 40 | { 41 | InspectorButtonAttribute inspectorButtonAttribute = (InspectorButtonAttribute)attribute; 42 | Rect buttonRect = new Rect(position.x + (position.width - inspectorButtonAttribute.ButtonWidth) * 0.5f, position.y, inspectorButtonAttribute.ButtonWidth, position.height); 43 | if (GUI.Button(buttonRect, label.text)) 44 | { 45 | System.Type eventOwnerType = prop.serializedObject.targetObject.GetType(); 46 | string eventName = inspectorButtonAttribute.MethodName; 47 | 48 | if (_eventMethodInfo == null) 49 | _eventMethodInfo = eventOwnerType.GetMethod(eventName, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); 50 | 51 | if (_eventMethodInfo != null) 52 | _eventMethodInfo.Invoke(prop.serializedObject.targetObject, null); 53 | else 54 | Debug.LogWarning(string.Format("InspectorButton: Unable to find method {0} in {1}", eventName, eventOwnerType)); 55 | } 56 | } 57 | } 58 | #endif 59 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | UnityPublic 2 | =========== 3 | 4 | A front-facing repository for various tools and boiler plate scripts. 5 | --------------------------------------------------------------------------------