Preview Main Component Icon In Hierachy

Hey guys,
I made a simple script that shows the icon of the first component (after transform of course) of the gameobject in hierarchy and also show a toggle to toggle the active state of the object.
It can also show custom component icons, you just need to put them in Assets/Editor/Icons.
Also, it has some “smart” icon showing that shows differently depending if the object has components or not and if it has childs or not, if it’s a prefab or not too:
Plus:
– Mass deactivate/activate gameobject and its children by holding alt and clicking on its toggle.
ps.: The children will inherit the toggled object’s active state, IT WILL NOT TOGGLE THE CHILD ACTIVE STATE.
– Choose to only show specific component types and etc.
– If custom component type was added to the specific component types and there is no icon for it, it will show a gameobject icon
Here is the code:
// Main Component Icon, Active State Toggling and "Smart Empty Object Icon Display"
using UnityEditor;
using UnityEngine;
using System;
using System.Collections.Generic;

[InitializeOnLoad]
class MainComponentIcon
{
// only show these types if showAllTypes is false
static Type[] componentTypes = new Type[]
{
typeof(Light),
typeof(BoxCollider),
typeof(Camera),
typeof(ParticleSystem),
typeof(TrailRenderer),
typeof(MeshRenderer),
typeof(MeshFilter),
typeof(SpriteRenderer),
typeof(AudioSource),
typeof(Canvas),
typeof(CanvasGroup),
typeof(UnityEngine.UI.Image),
typeof(UnityEngine.UI.Button),
typeof(UnityEngine.UI.Text),

// must add the custom types here if showAllTypes is false
//typeof(GameController),
//typeof(PlayerController),
//typeof(SpellScript)
};
static bool showActiveToggle = true;
static bool showIndentedActiveToggle = true;
static bool showAllTypes = true;
static bool useFallbackIconForExcludedComponents = false;
static bool prefabOverOthers = true; // don't show any component icon if the gameobject is a prefab, show the prefab icon instead
static bool alwaysShowCustom = false; // will show all custom, even if they don't have custom images (will show the little script page icon)
static bool alwaysShowPrefabContainer = true;
static IdleObjectsView showEmptyPrefabIconInIdleObjects = IdleObjectsView.TransformIcon; // // gameobjects with no child or components
static FallbackIcon fallbackIcon = FallbackIcon.GameObjectOrTransformsOrPrefab;

// UI exceptions
static bool canvasOverPrefab = true;

static List<GameObject> allChildGOsForToggle;
static bool toggleActiveAllChildInheritToggleObject = true; // Attention: if hold alt and clickin on object toggle, it will set all childs active state to the same of the clicked object

static MainComponentIcon()
{
// Init
EditorApplication.hierarchyWindowItemOnGUI += HierarchyItemCB;
}

static void HierarchyItemCB(int instanceID, Rect selectionRect)
{
GameObject obj = EditorUtility.InstanceIDToObject(instanceID) as GameObject;
var backupColor = GUI.color;

if (obj)
{
Rect r = new Rect(selectionRect);
if (showActiveToggle)
{
// Toggle active button
r.x = showIndentedActiveToggle ? selectionRect.x - 28 : 2;
r.width = 18;
r.height = 16;

EditorGUI.BeginChangeCheck();

backupColor = GUI.color;
if (!obj.activeInHierarchy && obj.transform.parent != null) GUI.color = new Color(GUI.color.r, GUI.color.g, GUI.color.b, 0.5f);
var toggleValue = GUI.Toggle(r, obj.activeSelf, "");
GUI.color = backupColor;
if (toggleActiveAllChildInheritToggleObject && Event.current.alt)
{
if (EditorGUI.EndChangeCheck())
{
if (allChildGOsForToggle == null) allChildGOsForToggle = new List<GameObject>();
allChildGOsForToggle.Clear();
allChildGOsForToggle.Add(obj);
FetchAllChildGameObjects(obj.transform);
Undo.RecordObjects(allChildGOsForToggle.ToArray(), "Toggle GameObjects Active");
allChildGOsForToggle.ForEach(child => child.SetActive(toggleValue));
}
}
else
{
if (EditorGUI.EndChangeCheck())
{
Undo.RecordObject(obj, "Toggle " + obj.name + " Active");
obj.SetActive(toggleValue);
}
}
}

// Icon
r.x = EditorGUIUtility.currentViewWidth - 38;
r.width = 18;
r.height = 18;
backupColor = GUI.color;
if (!obj.activeInHierarchy) GUI.color = new Color(GUI.color.r, GUI.color.g, GUI.color.b, 0.5f);
var components = obj.GetComponents<Component>();
if (components != null)
{
// FIRST COMPONENT IS ALWAYS TRANSFORM OR RECT TRASNFORM
if (components.Length > 1)
{
// HAS COMPONENTS
Type type = components[1].GetType();
Texture image = EditorGUIUtility.ObjectContent(null, type).image;
bool isInComponentTypesList = Array.Exists(componentTypes, x => x == type);

if (image == null)
{
// put your custom components icons in Assets/Editor/Icons, name it the same name of your class and change the extension below as accordingly
image = AssetDatabase.LoadAssetAtPath("Assets/Editor/Icons/" + type.ToString() + ".psd", typeof(Texture)) as Texture;
}

if (canvasOverPrefab && type == typeof(Canvas))
{
GUI.Label(r, EditorGUIUtility.IconContent("Canvas Icon"));
}
else if (prefabOverOthers && CanShowAsPrefab(obj))
{
ShowFallbackIcon(obj, r);
}
else if (!image && alwaysShowCustom)
{
GUI.Label(r, EditorGUIUtility.IconContent("cs Script Icon"));
}
else if (showAllTypes || isInComponentTypesList)
{
if (image)
{
GUI.Label(r, image);
}
else
{
ShowFallbackIcon(obj, r);
}
}
else if (image && useFallbackIconForExcludedComponents || alwaysShowPrefabContainer && CanShowAsPrefab(obj))
{
ShowFallbackIcon(obj, r);
}
}
else
{
// IDLE OBJECTS
if (obj.transform.childCount == 0)
{
if (CanShowAsPrefab(obj))
GUI.Label(r, EditorGUIUtility.IconContent("PrefabNormal Icon"));
else if (showEmptyPrefabIconInIdleObjects == IdleObjectsView.WhitePrefabIcon) // no child nor components
GUI.Label(r, EditorGUIUtility.IconContent("Prefab Icon"));
else if (showEmptyPrefabIconInIdleObjects == IdleObjectsView.TransformIcon) // no child nor components
{
if (obj.GetComponent<RectTransform>())
GUI.Label(r, EditorGUIUtility.IconContent("RectTransform Icon"));
else
GUI.Label(r, EditorGUIUtility.IconContent("Transform Icon"));
}
}
// NO COMPONENTS BUT HAS CHILDREN
else if (obj.transform.childCount > 0)
{
if (CanShowAsPrefab(obj))
GUI.Label(r, EditorGUIUtility.IconContent("PrefabNormal Icon"));
else
GUI.Label(r, EditorGUIUtility.IconContent("Prefab Icon"));

GUI.Label(r, EditorGUIUtility.IconContent("Transform Icon"));
}

}
}

GUI.color = backupColor;
}
}

static void ShowFallbackIcon(GameObject obj, Rect r)
{
switch (fallbackIcon)
{
case FallbackIcon.TransformOrRect:

if (obj.GetComponent<RectTransform>())
GUI.Label(r, EditorGUIUtility.IconContent("RectTransform Icon"));
else
GUI.Label(r, EditorGUIUtility.IconContent("Transform Icon"));
break;

case FallbackIcon.GameObjectOrPrefab:
if (CanShowAsPrefab(obj))
GUI.Label(r, EditorGUIUtility.IconContent("PrefabNormal Icon"));
else
GUI.Label(r, EditorGUIUtility.IconContent("GameObject Icon"));
break;

case FallbackIcon.GameObjectOrTransformsOrPrefab:
if (CanShowAsPrefab(obj))
GUI.Label(r, EditorGUIUtility.IconContent("PrefabNormal Icon"));
else
{
if (obj.GetComponents<Component>().Length > 1)
{
GUI.Label(r, EditorGUIUtility.IconContent("GameObject Icon"));
}
else
{
GUI.Label(r, EditorGUIUtility.IconContent("Transform Icon"));
}
}
break;
}
}

static bool IsPartOfPrefab(GameObject prefab)
{
return PrefabUtility.GetPrefabParent(prefab) != null;
}

static bool IsPrefabParent(GameObject prefab)
{
return PrefabUtility.FindPrefabRoot(prefab) == prefab;
}

static bool CanShowAsPrefab(GameObject prefab)
{
if (IsPrefabParent(prefab) &&
IsPartOfPrefab(prefab) &&
PrefabUtility.GetPrefabType(prefab) == PrefabType.PrefabInstance ||
PrefabUtility.GetPrefabType(prefab) == PrefabType.ModelPrefabInstance)
{
return true;
}

return false;
}

public static void FetchAllChildGameObjects(Transform transform)
{
if (allChildGOsForToggle == null) allChildGOsForToggle = new List<GameObject>();
foreach (Transform t in transform)
{
if (!allChildGOsForToggle.Contains(t.gameObject)) allChildGOsForToggle.Add(t.gameObject);
FetchAllChildGameObjects(t);
}
}

//static bool
}

enum FallbackIcon
{
None,
GameObjectOrTransformsOrPrefab,
GameObjectOrPrefab,
TransformOrRect
}

enum IdleObjectsView
{
None,
TransformIcon,
WhitePrefabIcon
}

 

I hope you enjoy!

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s