Unity Editor Scripting – Filtering Hierarchy by Tag or Layer

Today I’m going to show and share an editor code I wrote about how to filter your hierarchy by tag or layer. I uploaded my editor scripts to this repository on Github, if you read my previous editor tutorials you should have seen this script inside /Tut-2-FilterHierarchy folder.

The default filtering option for Unity’s hierarchy window is by name and type. So far so good but many people think there should be a builtin filtering with tag and layer. But anyway you can write a simple editor window script to do that. Here is what I did;

  • If list is not empty assign them to your Selection. And you have your hierarchy filtered thats it!
  • Loop through those gameobjects and compare their tag or layer with desired ones and add to list if it’s equal.
  • Create a new list to hold the filtered gameobjects.
  • Get all objects or selected objects in hierarchy view(using FindObjectsOfTypeAll or FindObjectsOfType methods)
  • Getting gameobjects in hierarchy view

To get the objects in our hierarchy view we are going to use two methods, first one is for getting active and nonactive gameobjects, using Resources class:

Object[] selectAll ()
{
  return Resources.FindObjectsOfTypeAll(typeof(GameObject)) as Object[];
}

And for getting only the active objects we are going to use Object class:

Object[] selectActive ()
{
  return Object.FindObjectsOfType(typeof(GameObject)) as Object[];
}
  • Finding the gameobjects with tag or layer

After selecting all objects in our hierarchy view we are going to loop through them and check if their tag or layer is same with the one that we choose.

// get all the gameobjects
Object[] selected = filterInactive ? selectAll() : selectActive();
// make a list to hold the indexes of gameobjects
objectIndex = new List<int>();
// loop through them
for(int i = 0; i< selected.Length; i++)
 {
  // get gameobject
  GameObject g = (GameObject)selected[i] as GameObject;
  // check if we are filtering tag and if tag is same
  if(ops == FilterOptions.Tag && g.tag == selectedTag)
  {
  // add to index
   objectIndex.Add(i);
  }
  else if(ops == FilterOptions.Layer && g.layer == layer)
  {
   objectIndex.Add(i);
  }
  else if(ops == FilterOptions.Both && g.layer == layer && g.tag == selectedTag)
  {
   objectIndex.Add(i);
  }
 }

After finding our desired gameobjects we are going to make them our selection:

Object[] newSelected = new Object[objectIndex.Count];
for(int i = 0; i< objectIndex.Count; i++)
{
 newSelected[i] = selected[objectIndex[i]];
}
Selection.objects = newSelected;</pre>

With this code we are making an array of new Objects and filling the array with our desired tag or layer option and assign it to our selection so we can see them. Here is the whole code for this editor window:

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEditor;

enum FilterOptions
{
 Tag,Layer,Both
}
public class FilterHierarcyEditor : EditorWindow {

 FilterOptions filterOptions = FilterOptions.Tag;
 string selectedTag = "Untagged";
 int layer = 0;
 bool filterInactive;
 List<int> objectIndex = new List<int>();

[MenuItem("Custom/Filter Hierarcy")]
static void Init()
{
  FilterHierarcyEditor filter = (FilterHierarcyEditor)EditorWindow.GetWindow (typeof (FilterHierarcyEditor));
  filter.Show();
}
void OnGUI () {
 EditorGUILayout.PrefixLabel("Filtering Options");
 filterInactive = EditorGUILayout.Toggle("Filter Inactive",filterInactive);
 filterOptions =(FilterOptions) EditorGUILayout.EnumPopup("Filter By",filterOptions);
 if(filterOptions == FilterOptions.Tag)
 {
  selectedTag = EditorGUILayout.TagField("Select Tag",selectedTag);
  if(GUILayout.Button("Filter by Tag"))
  {
   filterSelected(filterOptions);
  }
 }
 else if(filterOptions == FilterOptions.Layer)
 {
  layer = EditorGUILayout.LayerField("Select Layer",layer);
  if(GUILayout.Button("Filter by Layer"))
  {
   filterSelected(filterOptions);
  }
 }
 else
 {
  selectedTag = EditorGUILayout.TagField("Select Tag",selectedTag);
  layer = EditorGUILayout.LayerField("Select Layer",layer);
  if(GUILayout.Button("Filter by All"))
  {
   filterSelected(filterOptions);
  }
 }
// EditorGUILayout.PrefixLabel("Save and Load Options");
 EditorGUILayout.Space();
 EditorGUILayout.BeginHorizontal();
 if(Selection.objects.Length >= 1)
 {
  if(GUILayout.Button("Save Selection"))
  {
   int[] selectionIDs = Selection.instanceIDs;
   var saveStr = string.Empty;
   foreach( int i in selectionIDs)
   saveStr += i.ToString() + ";";
   saveStr = saveStr.TrimEnd(char.Parse(";"));
   EditorPrefs.SetString("SelectedIDs",saveStr);
  }
 }
 if(EditorPrefs.HasKey("SelectedIDs"))
 {
  if(GUILayout.Button("Load Selection"))
  {
   string[] strIDs= EditorPrefs.GetString("SelectedIDs").Split(char.Parse(";"));
   int[] ids = new int[strIDs.Length];
   for(var i = 0; i < strIDs.Length; i++)
   ids[i] = int.Parse(strIDs[i]);
   Selection.instanceIDs = ids;
  }
 }
 EditorGUILayout.EndHorizontal();
 }

void OnInspectorUpdate() {
 Repaint();
}

Object[] selectAll ()
{
 return Resources.FindObjectsOfTypeAll(typeof(GameObject)) as Object[];
}
Object[] selectActive ()
{
 return Object.FindObjectsOfType(typeof(GameObject)) as Object[];
}

void filterSelected (FilterOptions ops)
{

 Object[] selected = filterInactive ? selectAll() : selectActive();

 objectIndex = new List<int>();
 for(int i = 0; i< selected.Length; i++)
 {
  GameObject g = (GameObject)selected[i] as GameObject;

  if(ops == FilterOptions.Tag && g.tag == selectedTag)
  {
   objectIndex.Add(i);
  }
  else if(ops == FilterOptions.Layer && g.layer == layer)
  {
   objectIndex.Add(i);
  }
  else if(ops == FilterOptions.Both && g.layer == layer && g.tag == selectedTag)
  {
  objectIndex.Add(i);
  }
 }
 Object[] newSelected = new Object[objectIndex.Count];
 for(int i = 0; i< objectIndex.Count; i++)
 {
  newSelected[i] = selected[objectIndex[i]];
 }
  Selection.objects = newSelected;
 }
}

That’s all for this tutorial. You can download the code from here. Next time I will update this code with modifying the hideflag options of gameobjects so stay tuned!

Advertisements

One Comment Add yours

  1. Wuxingogo says:

    Object[] selectAll ()
    {
    return Resources.FindObjectsOfTypeAll(typeof(GameObject)) as Object[];
    };

    Can’t get unactive Object. Would you have a better method?

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