{"id":1708,"date":"2016-12-07T02:18:47","date_gmt":"2016-12-06T18:18:47","guid":{"rendered":"http:\/\/www.clonefactor.com\/wordpress\/?p=1708"},"modified":"2016-12-07T02:36:45","modified_gmt":"2016-12-06T18:36:45","slug":"unity3d-custompropertydrawer-for-attribute-editor","status":"publish","type":"post","link":"https:\/\/www.clonefactor.com\/wordpress\/program\/unity3d\/1708\/","title":{"rendered":"Unity3D : CustomPropertyDrawer for Attribute \/ Editor."},"content":{"rendered":"<p>it&#8217;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.<br \/>\nso I decide to create my own tag field by using Unity editor API.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1709\" src=\"http:\/\/www.clonefactor.com\/wordpress\/wp-content\/uploads\/2016\/12\/CustomPropertyDrawer_01.jpg\" alt=\"custompropertydrawer_01\" width=\"457\" height=\"97\" srcset=\"https:\/\/www.clonefactor.com\/wordpress\/wp-content\/uploads\/2016\/12\/CustomPropertyDrawer_01.jpg 457w, https:\/\/www.clonefactor.com\/wordpress\/wp-content\/uploads\/2016\/12\/CustomPropertyDrawer_01-300x64.jpg 300w\" sizes=\"auto, (max-width: 457px) 100vw, 457px\" \/><\/p>\n<p>first the game tag must require a\u00a0string variable. and we will require an Attribute to describe the variable are used for game tag.<br \/>\nso we create a empty attribute class for identify purpose.<\/p>\n<pre class=\"brush:csharp\">public class TagFieldAttribute : UnityEngine.PropertyAttribute { }<\/pre>\n<p>after created a attribute, you may notify your IDE already locate your attribute class and able to use it for any variable.<br \/>\nin this case we wanted to apply that attriabute on string type variable.<\/p>\n<pre class=\"brush:csharp\">[TagFieldAttribute] public string m_TestTag;<\/pre>\n<p>however in this point you are not able to visualize the result. you only define a &#8220;TagField&#8221; attribute but haven&#8217;t told the editor how to draw it.<br \/>\nhere is my\u00a0editor script to override the string type property and draw it use the EditorGUI.TagField() API.<\/p>\n<pre class=\"brush:csharp\">public sealed class EditorExtend\r\n{\r\n\tpublic static string TagField(Rect position, SerializedProperty property, GUIContent label)\r\n\t{\r\n\t\tstring layerName = property.stringValue;\r\n\t\tEditorGUI.BeginChangeCheck();\r\n\t\tif (string.IsNullOrEmpty(layerName))\r\n\t\t{\r\n\t\t\tlayerName = \"Untagged\";\r\n\t\t\tproperty.stringValue = layerName;\r\n\t\t}\r\n\t\tlayerName = EditorGUI.TagField(position, label, layerName);\r\n\t\tif (EditorGUI.EndChangeCheck())\r\n\t\t{\r\n\t\t\tproperty.stringValue = layerName;\r\n\t\t}\r\n\t\treturn layerName;\r\n\t}\r\n}<\/pre>\n<p>these script are only able to used in editor, it&#8217;s good enough\u00a0to use when you have time to customize your own inspector.<br \/>\nbut hard to use if you only wanted to apply this on single variable (and too lazy to write\u00a0the whole inspector script). so we need to define a CustomPropertyDrawer for this attribute (TagFieldAttribute)<\/p>\n<pre class=\"brush:csharp\">[CustomPropertyDrawer(typeof(TagFieldAttribute))]\r\npublic class TagFieldDrawer : PropertyDrawer\r\n{\r\n\tTagFieldAttribute tagFieldAttribute { get { return (TagFieldAttribute)attribute; } }\r\n\r\n\tpublic override void OnGUI(Rect position, SerializedProperty property, GUIContent label)\r\n\t{\r\n\t\tEditorGUI.BeginProperty(position, label, property);\r\n\t\tif (property.propertyType == SerializedPropertyType.String)\r\n\t\t{\r\n\t\t\tEditorExtend.TagField(position, property, label);\r\n\t\t}\r\n\t\telse\r\n\t\t{\r\n\t\t\tEditorGUI.LabelField(position, label, typeof(TagFieldAttribute).Name + \" only allow to use with { String }.\");\r\n\t\t}\r\n\t\tEditorGUI.EndProperty();\r\n\t}\r\n}<\/pre>\n<p>after all this script compiled, you will find the inspector start to using your custom drawer for display the variable.<\/p>\n<pre class=\"brush:csharp\">[TagField] public string m_TestTag;<\/pre>\n<figure id=\"attachment_1710\" aria-describedby=\"caption-attachment-1710\" style=\"width: 446px\" class=\"wp-caption alignnone\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-1710 size-full\" src=\"http:\/\/www.clonefactor.com\/wordpress\/wp-content\/uploads\/2016\/12\/CustomPropertyDrawer_02.jpg\" alt=\"custompropertydrawer_02\" width=\"446\" height=\"36\" srcset=\"https:\/\/www.clonefactor.com\/wordpress\/wp-content\/uploads\/2016\/12\/CustomPropertyDrawer_02.jpg 446w, https:\/\/www.clonefactor.com\/wordpress\/wp-content\/uploads\/2016\/12\/CustomPropertyDrawer_02-300x24.jpg 300w\" sizes=\"auto, (max-width: 446px) 100vw, 446px\" \/><figcaption id=\"caption-attachment-1710\" class=\"wp-caption-text\">from this &#8220;string&#8221;<\/figcaption><\/figure>\n<figure id=\"attachment_1711\" aria-describedby=\"caption-attachment-1711\" style=\"width: 450px\" class=\"wp-caption alignnone\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-1711 size-full\" src=\"http:\/\/www.clonefactor.com\/wordpress\/wp-content\/uploads\/2016\/12\/CustomPropertyDrawer_03.jpg\" alt=\"custompropertydrawer_03\" width=\"450\" height=\"241\" srcset=\"https:\/\/www.clonefactor.com\/wordpress\/wp-content\/uploads\/2016\/12\/CustomPropertyDrawer_03.jpg 450w, https:\/\/www.clonefactor.com\/wordpress\/wp-content\/uploads\/2016\/12\/CustomPropertyDrawer_03-300x161.jpg 300w\" sizes=\"auto, (max-width: 450px) 100vw, 450px\" \/><figcaption id=\"caption-attachment-1711\" class=\"wp-caption-text\">become this ! (Result)<\/figcaption><\/figure>\n<p>&nbsp;<\/p>\n<p>PS, if you done it right, it should also able to use it on arrays.<\/p>\n<pre class=\"brush:csharp\">[TagField] public string[] m_TestTag;<\/pre>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1712\" src=\"http:\/\/www.clonefactor.com\/wordpress\/wp-content\/uploads\/2016\/12\/CustomPropertyDrawer_04.jpg\" alt=\"custompropertydrawer_04\" width=\"457\" height=\"193\" srcset=\"https:\/\/www.clonefactor.com\/wordpress\/wp-content\/uploads\/2016\/12\/CustomPropertyDrawer_04.jpg 457w, https:\/\/www.clonefactor.com\/wordpress\/wp-content\/uploads\/2016\/12\/CustomPropertyDrawer_04-300x127.jpg 300w\" sizes=\"auto, (max-width: 457px) 100vw, 457px\" \/><\/p>\n","protected":false},"excerpt":{"rendered":"<p>it&#8217;s too easy to create your custom property &hellip;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[11],"tags":[20,43],"class_list":["post-1708","post","type-post","status-publish","format-standard","hentry","category-unity3d","tag-editor","tag-unity3d-2"],"_links":{"self":[{"href":"https:\/\/www.clonefactor.com\/wordpress\/wp-json\/wp\/v2\/posts\/1708","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.clonefactor.com\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.clonefactor.com\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.clonefactor.com\/wordpress\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.clonefactor.com\/wordpress\/wp-json\/wp\/v2\/comments?post=1708"}],"version-history":[{"count":0,"href":"https:\/\/www.clonefactor.com\/wordpress\/wp-json\/wp\/v2\/posts\/1708\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.clonefactor.com\/wordpress\/wp-json\/wp\/v2\/media?parent=1708"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.clonefactor.com\/wordpress\/wp-json\/wp\/v2\/categories?post=1708"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.clonefactor.com\/wordpress\/wp-json\/wp\/v2\/tags?post=1708"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}