Unity3D : CustomPropertyDrawer for Attribute / Editor.

it’s too easy to create your custom property drawer, I always feel the Unity3D editor require developer to type the correct game tag are really annoying.
so I decide to create my own tag field by using Unity editor API.

custompropertydrawer_01

first the game tag must require a string variable. and we will require an Attribute to describe the variable are used for game tag.
so we create a empty attribute class for identify purpose.

public class TagFieldAttribute : UnityEngine.PropertyAttribute { }

after created a attribute, you may notify your IDE already locate your attribute class and able to use it for any variable.
in this case we wanted to apply that attriabute on string type variable.

[TagFieldAttribute] public string m_TestTag;

however in this point you are not able to visualize the result. you only define a “TagField” attribute but haven’t told the editor how to draw it.
here is my editor script to override the string type property and draw it use the EditorGUI.TagField() API.

public sealed class EditorExtend
{
	public static string TagField(Rect position, SerializedProperty property, GUIContent label)
	{
		string layerName = property.stringValue;
		EditorGUI.BeginChangeCheck();
		if (string.IsNullOrEmpty(layerName))
		{
			layerName = "Untagged";
			property.stringValue = layerName;
		}
		layerName = EditorGUI.TagField(position, label, layerName);
		if (EditorGUI.EndChangeCheck())
		{
			property.stringValue = layerName;
		}
		return layerName;
	}
}

these script are only able to used in editor, it’s good enough to use when you have time to customize your own inspector.
but hard to use if you only wanted to apply this on single variable (and too lazy to write the whole inspector script). so we need to define a CustomPropertyDrawer for this attribute (TagFieldAttribute)

[CustomPropertyDrawer(typeof(TagFieldAttribute))]
public class TagFieldDrawer : PropertyDrawer
{
	TagFieldAttribute tagFieldAttribute { get { return (TagFieldAttribute)attribute; } }

	public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
	{
		EditorGUI.BeginProperty(position, label, property);
		if (property.propertyType == SerializedPropertyType.String)
		{
			EditorExtend.TagField(position, property, label);
		}
		else
		{
			EditorGUI.LabelField(position, label, typeof(TagFieldAttribute).Name + " only allow to use with { String }.");
		}
		EditorGUI.EndProperty();
	}
}

after all this script compiled, you will find the inspector start to using your custom drawer for display the variable.

[TagField] public string m_TestTag;
custompropertydrawer_02

from this “string”

custompropertydrawer_03

become this ! (Result)

 

PS, if you done it right, it should also able to use it on arrays.

[TagField] public string[] m_TestTag;

custompropertydrawer_04

發表迴響

你的電子郵件位址並不會被公開。 必要欄位標記為 *

*