Object Drawers

Object Drawers are very similar to the Unity feature Property Drawers. Object drawers allow you to customize the look of different objects within the inspector. As an example, we will modify the Shared Custom Object example found in the Creating Your Own Shared Variable topic. With the default inspector, the SharedCustomClass variable looks like the following in the inspector:

For this example, we will limit the range of the integer between 0 and 10 using object drawers:

The following object drawer was used to accomplish this (this script goes in an Editor folder):

using UnityEngine;
using UnityEditor;
using BehaviorDesigner.Editor;

[CustomObjectDrawer(typeof(CustomClass))]
public class CustomClassDrawer : ObjectDrawer
{
   public override void OnGUI(GUIContent label)
   {
      var customClass = value as CustomClass;
      EditorGUILayout.BeginVertical();
      if (FieldInspector.DrawFoldout(customClass.GetHashCode(), label)) {
         EditorGUI.indentLevel++;
         customClass.myInt = EditorGUILayout.IntSlider("Integer", customClass.myInt, 0, 10);
         customClass.myObject = EditorGUILayout.ObjectField("Object", customClass.myObject, typeof(UnityEngine.Object), true);
         EditorGUI.indentLevel--;
      }
      EditorGUILayout.EndVertical();
   }
}

The only method that you need to override for object drawers to work is the OnGUI(GUIContent label) method. The label field is the name of the field that is being drawn. Just like property drawers, you can specify a object drawer by the class type or by attributes. The example above is using the class type method.

As another example, we will convert the Ranged Attribute used in Unity’s example to a Object Drawer. First we need to create the attribute:

using UnityEngine;
using BehaviorDesigner.Runtime.Tasks;
using BehaviorDesigner.Runtime.ObjectDrawers;

public class RangeAttribute : ObjectDrawerAttribute
{
   public float min;
   public float max;

   public RangeAttribute(float min, float max)
   {
      this.min = min;
      this.max = max;
   }
}

Now that the attribute is created, we need to create the actual object drawer (this script goes in an Editor folder):

using UnityEngine;
using UnityEditor;
using BehaviorDesigner.Editor;

[CustomObjectDrawer(typeof(RangeAttribute))]
public class RangeDrawer : ObjectDrawer
{
   public override void OnGUI(GUIContent label)
   {
      var rangeAttribute = (RangeAttribute)attribute;
      value = EditorGUILayout.Slider(label, (float)value, rangeAttribute.min, rangeAttribute.max);
   }
}

Once both of these have been created, we can use it within a task:

using UnityEngine;
using BehaviorDesigner.Runtime;
using BehaviorDesigner.Runtime.Tasks;
using BehaviorDesigner.Runtime.ObjectDrawers;

public class NewAction : Action
{
   [Range(5, 10)]
   public float rangedFloat;
   public override TaskStatus OnUpdate()
   {
      Debug.Log(rangedFloat);
      return TaskStatus.Success;
   }
}

This will show up in the task inspector as: