I want to add my five cents, because I didn’t find this information upper.
If we compare the Drawer solution for a specific field (type) in an Inspector based on a “CustomEditor or PropertyDrawer”, the main differences (and different uses) will be:
- In case the "PropertyDrawer" the can write Drawer for Type (Class) only which not derived from MonoBehaviour or ScriptableObject you must create “Clean C# Data Class” (or use a standard Types that is possible, but doesn’t make a lot of sense)
- In case the “CustomEditor” we can also write Drawer to any Custom Class (include typical MonoBehaviour scripts etc.)
Also the “PropertyDrawer” only give possibility to change appearance & acting in Inspector (OnGUI / CreatePropertyGUI), the “CustomEditor” also can possibility to change appearance & acting in Scene View (OnInspectorGUI and OnSceneGUI and many others).
The simple Example use both variants together:
Exist Custom Type (“Class”) CameraMode and “MonoBehaviour Class” LookAtPoint. In Scene One GameObject with script LookAtPoint (the both “drawers” in any directory named the Editor)
using UnityEngine;
public enum CameraMode : byte
{
LockedOn,
LookAt,
Free
}
public class LookAtPoint : MonoBehaviour
{
[SerializeField] private Transform Target;
[SerializeField] private CameraMode CamMode;
public Vector3 PositionTarget => Target.position;
void Update()
{
transform.LookAt(Target);
}
public void UpdatePositionTarget(Vector3 newPostiion)
{
Target.position = newPostiion;
Update();
}
}
Simple Drawer for CameraMode (only change label before field in Inspector)
using UnityEngine;
using UnityEditor;
[CustomPropertyDrawer(typeof(CameraMode))]
public class CameraModeDrawer : PropertyDrawer
{
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
EditorGUI.BeginProperty(position, null, property);
EditorGUI.PropertyField(position, property, new GUIContent("Mode of Cam"));
EditorGUI.EndProperty();
}
}
And Drawer for LookAtPoint also very simple only change order of fields in Inspector and also add functionality to Scene View
using UnityEditor;
using UnityEngine;
[CustomEditor(typeof(LookAtPoint))]
public class LookAtPointEditor : Editor
{
SerializedProperty lookAtPoint;
SerializedProperty camMode;
void OnEnable()
{
lookAtPoint = serializedObject.FindProperty("Target");
camMode = serializedObject.FindProperty("CamMode");
}
public override void OnInspectorGUI()
{
serializedObject.Update();
EditorGUILayout.PropertyField(camMode);
EditorGUILayout.PropertyField(lookAtPoint);
serializedObject.ApplyModifiedProperties();
}
public void OnSceneGUI()
{
LookAtPoint t = (target as LookAtPoint);
EditorGUI.BeginChangeCheck();
Vector3 pos = Handles.PositionHandle(new Vector3(t.PositionTarget.x, t.PositionTarget.y, t.PositionTarget.z), Quaternion.identity);
if (EditorGUI.EndChangeCheck())
{
Undo.RecordObject(t.Target, "Move point");
t.UpdatePositionTarget(new Vector3(pos.x, pos.y, pos.z));
}
}
}
P.S> The Property Attributes is a more universal PropertyDrawer (it give many useful possibilities but you must design it more careful because the attribute can set to any field type). @BMayne and other wrote many useful, but more detail