Using tags as a dropdown property in Unity 5’s inspector using PropertyDrawers

If you have ever tried to use tags as a variable input property in a Unity inspector script, you have probably used a regular string property or an array of them.
Then you would be manually typing the tags you want to use in your script, having to double check if they are written correctly and part of the tags that are currently available in your project.
This works just fine but can lead to user input errors and is just plain annoying to use.

Luckily there is a simple solution for this problem!
Using a custom attribute we can visualize our string as a drop-down popup that lists all the available tags, allowing us to select the tag we want and having the selected value automatically assigned to our string.

TagSelectorAttribute Example

Using the attribute

In order to use the attribute all you have to do is add the attribute in front of a string or string array property.

using UnityEngine;
using System.Collections;

public class TagSelectorExample : MonoBehaviour
{
    [TagSelector]
    public string TagFilter = "";

    [TagSelector]
    public string[] TagFilterArray = new string[] { };
}

Creating the PropertyDrawer

The following code has been based on the TagSelector attribute made by Dylan Engelman (http://jupiterlighthousestudio.com/custom-inspectors-unity/).
I have made some adjustments to extend the use of the attribute and make it easier to extend upon.

Just as with the Hiding or Disabling inspector properties using PropertyDrawers within Unity 5 article, the TagSelectorPropertyDrawer script needs to be placed inside of an editor folder within the project.

TagSelector Attribute

using UnityEngine;

public class TagSelectorAttribute : PropertyAttribute
{
    public bool UseDefaultTagFieldDrawer = false;
}

TagSelectorPropertyDrawer

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

//Original by DYLAN ENGELMAN http://jupiterlighthousestudio.com/custom-inspectors-unity/
//Altered by Brecht Lecluyse http://www.brechtos.com

[CustomPropertyDrawer(typeof(TagSelectorAttribute))]
using UnityEngine;
using UnityEditor;
using System.Collections.Generic;

//Original by DYLAN ENGELMAN http://jupiterlighthousestudio.com/custom-inspectors-unity/
//Altered by Brecht Lecluyse http://www.brechtos.com

[CustomPropertyDrawer(typeof(TagSelectorAttribute))]
public class TagSelectorPropertyDrawer : PropertyDrawer
{

    public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
    {
        if (property.propertyType == SerializedPropertyType.String)
        {
            EditorGUI.BeginProperty(position, label, property);

            var attrib = this.attribute as TagSelectorAttribute;

            if (attrib.UseDefaultTagFieldDrawer)
            {
                property.stringValue = EditorGUI.TagField(position, label, property.stringValue);
            }
            else
            {
                //generate the taglist + custom tags
                List<string> tagList = new List<string>();
                tagList.Add("<NoTag>");
                tagList.AddRange(UnityEditorInternal.InternalEditorUtility.tags);
                string propertyString = property.stringValue;
                int index = -1;
                if(propertyString =="")
                {
                    //The tag is empty
                    index = 0; //first index is the special <notag> entry
                }
                else
                {
                    //check if there is an entry that matches the entry and get the index
                    //we skip index 0 as that is a special custom case
                    for (int i = 1; i < tagList.Count; i++)
                    {
                        if (tagList[i] == propertyString)
                        {
                            index = i;
                            break;
                        }
                    }
                }
               
                //Draw the popup box with the current selected index
                index = EditorGUI.Popup(position, label.text, index, tagList.ToArray());

                //Adjust the actual string value of the property based on the selection
                if(index==0)
                {
                    property.stringValue = "";
                }
                else if (index >= 1)
                {
                    property.stringValue = tagList[index];
                }
                else
                {
                    property.stringValue = "";
                }
            }

            EditorGUI.EndProperty();
        }
        else
        {
            EditorGUI.PropertyField(position, property, label);
        }
    }
}

And that’s all there is to it. I hope this will be of use to some of you :).

-Brecht

Leave a Reply