Inspector
GameObject Editor
(built-in)
Transform Editor
(built-in)
Generic Editor
Enemy
Generic Editor
Enemy
using UnityEngine;
public class Enemy : MonoBehaviour {
public float speed = 5;
public float maxHealth = 10;
void Update () {
}
}
Generic Editor
Enemy
Custom Editor
Enemy
+
Editor
EnemyEditor
Custom Editors
Enemy
using UnityEngine;
public class Enemy : MonoBehaviour {
public float speed = 5;
public float maxHealth = 10;
void Update () {
}
}
EnemyEditor
using UnityEngine;
using UnityEditor;
[CustomEditor (typeof (Enemy))]
public class EnemyEditor : Editor {
}
SerializedProperty speed;
SerializedProperty maxHealth;
public void OnEnable () {
speed = serializedObject.FindProperty ("speed");
maxHealth = serializedObject.FindProperty ("maxHealth");
}
public override void OnInspectorGUI () {
serializedObject.Update ();
EditorGUILayout.PropertyField (speed);
EditorGUILayout.PropertyField (maxHealth);
serializedObject.ApplyModifiedProperties ();
}
EnemyEditor
using UnityEngine;
using UnityEditor;
[CustomEditor (typeof (Enemy))]
public class EnemyEditor : Editor {
}
SerializedProperty speed;
SerializedProperty maxHealth;
public void OnEnable () {
speed = serializedObject.FindProperty ("speed");
maxHealth = serializedObject.FindProperty ("maxHealth");
}
public override void OnInspectorGUI () {
serializedObject.Update ();
EditorGUILayout.PropertyField (speed);
EditorGUILayout.PropertyField (maxHealth);
serializedObject.ApplyModifiedProperties ();
}
EnemyEditor
using UnityEngine;
using UnityEditor;
[CustomEditor (typeof (Enemy))]
public class EnemyEditor : Editor {
}
SerializedProperty speed;
SerializedProperty maxHealth;
public void OnEnable () {
speed = serializedObject.FindProperty ("speed");
maxHealth = serializedObject.FindProperty ("maxHealth");
}
public override void OnInspectorGUI () {
serializedObject.Update ();
EditorGUILayout.PropertyField (speed);
EditorGUILayout.PropertyField (maxHealth);
serializedObject.ApplyModifiedProperties ();
}
EnemyEditor
using UnityEngine;
using UnityEditor;
[CustomEditor (typeof (Enemy))]
public class EnemyEditor : Editor {
}
SerializedProperty speed;
SerializedProperty maxHealth;
public void OnEnable () {
speed = serializedObject.FindProperty ("speed");
maxHealth = serializedObject.FindProperty ("maxHealth");
}
public override void OnInspectorGUI () {
serializedObject.Update ();
EditorGUILayout.PropertyField (speed);
EditorGUILayout.PropertyField (maxHealth);
serializedObject.ApplyModifiedProperties ();
}
EnemyEditor
using UnityEngine;
using UnityEditor;
[CustomEditor (typeof (Enemy))]
public class EnemyEditor : Editor {
}
SerializedProperty speed;
SerializedProperty maxHealth;
public void OnEnable () {
speed = serializedObject.FindProperty ("speed");
maxHealth = serializedObject.FindProperty ("maxHealth");
}
public override void OnInspectorGUI () {
serializedObject.Update ();
EditorGUILayout.PropertyField (speed);
EditorGUILayout.PropertyField (maxHealth);
serializedObject.ApplyModifiedProperties ();
}
EnemyEditor
using UnityEngine;
using UnityEditor;
[CustomEditor (typeof (Enemy))]
public class EnemyEditor : Editor {
}
SerializedProperty speed;
SerializedProperty maxHealth;
public void OnEnable () {
speed = serializedObject.FindProperty ("speed");
maxHealth = serializedObject.FindProperty ("maxHealth");
}
public override void OnInspectorGUI () {
serializedObject.Update ();
EditorGUILayout.PropertyField (speed);
EditorGUILayout.PropertyField (maxHealth);
serializedObject.ApplyModifiedProperties ();
}
EnemyEditor
using UnityEngine;
using UnityEditor;
[CustomEditor (typeof (Enemy))]
public class EnemyEditor : Editor {
}
SerializedProperty speed;
SerializedProperty maxHealth;
public void OnEnable () {
speed = serializedObject.FindProperty ("speed");
maxHealth = serializedObject.FindProperty ("maxHealth");
}
public override void OnInspectorGUI () {
serializedObject.Update ();
EditorGUILayout.PropertyField (speed);
EditorGUILayout.PropertyField (maxHealth);
serializedObject.ApplyModifiedProperties ();
}
EnemyEditor
using UnityEngine;
using UnityEditor;
[CustomEditor (typeof (Enemy))]
public class EnemyEditor : Editor {
}
SerializedProperty speed;
SerializedProperty maxHealth;
public void OnEnable () {
speed = serializedObject.FindProperty ("speed");
maxHealth = serializedObject.FindProperty ("maxHealth");
}
public override void OnInspectorGUI () {
serializedObject.Update ();
EditorGUILayout.PropertyField (speed);
EditorGUILayout.Slider (maxHealth, 0, 10);
serializedObject.ApplyModifiedProperties ();
}
Why
SerializedProperties?
SerializedProperty advantages
SerializedProperty advantages
Undo/Redo
SerializedProperty advantages
Undo/Redo
Automatic multi-object editing
SerializedProperty advantages
Undo/Redo
Automatic multi-object editing
Prefab styling / reverting
EnemyEditor
using UnityEngine;
using UnityEditor;
[CustomEditor (typeof (Enemy))]
public class EnemyEditor : Editor {
}
SerializedProperty speed;
SerializedProperty maxHealth;
public void OnEnable () {
speed = serializedObject.FindProperty ("speed");
maxHealth = serializedObject.FindProperty ("maxHealth");
}
public override void OnInspectorGUI () {
serializedObject.Update ();
EditorGUILayout.PropertyField (speed);
EditorGUILayout.PropertyField (maxHealth);
serializedObject.ApplyModifiedProperties ();
}
EnemyEditor
using UnityEngine;
using UnityEditor;
[CustomEditor (typeof (Enemy))]
[CanEditMultipleObjects]
public class EnemyEditor : Editor {
}
SerializedProperty speed;
SerializedProperty maxHealth;
public void OnEnable () {
speed = serializedObject.FindProperty ("speed");
maxHealth = serializedObject.FindProperty ("maxHealth");
}
public override void OnInspectorGUI () {
serializedObject.Update ();
EditorGUILayout.PropertyField (speed);
EditorGUILayout.PropertyField (maxHealth);
serializedObject.ApplyModifiedProperties ();
}
EnemyEditor
using UnityEngine;
using UnityEditor;
[CustomEditor (typeof (Enemy))]
[CanEditMultipleObjects]
public class EnemyEditor : Editor {
}
SerializedProperty speed;
SerializedProperty maxHealth;
public void OnEnable () {
speed = serializedObject.FindProperty ("speed");
maxHealth = serializedObject.FindProperty ("maxHealth");
}
public override void OnInspectorGUI () {
serializedObject.Update ();
EditorGUILayout.PropertyField (speed);
EditorGUILayout.PropertyField (maxHealth);
serializedObject.ApplyModifiedProperties ();
}
PropertyDrawers
Added in Unity 4
PropertyDrawers
Enemy
using UnityEngine;
public class Enemy : MonoBehaviour {
public float speed = 5;
[Range (0, 10)]
public float maxHealth = 10;
void Update () {
}
}
Game script
Reusable code
Enemy
RangeAttribute
Editor
RangeDrawer
RangeAttribute
public class RangeAttribute : PropertyAttribute {
public float min;
public float max;
public RangeAttribute (float min, float max) {
this.min = min;
this.max = max;
}
}
RangeDrawer
[CustomPropertyDrawer (typeof (RangeAttribute))]
public class RangeDrawer : PropertyDrawer {
RangeAttribute
public class RangeAttribute : PropertyAttribute {
public float min;
public float max;
public RangeAttribute (float min, float max) {
this.min = min;
this.max = max;
}
}
RangeDrawer
[CustomPropertyDrawer (typeof (RangeAttribute))]
public class RangeDrawer : PropertyDrawer {
RangeAttribute
public class RangeAttribute : PropertyAttribute {
public float min;
public float max;
public RangeAttribute (float min, float max) {
this.min = min;
this.max = max;
}
}
RangeDrawer
[CustomPropertyDrawer (typeof (RangeAttribute))]
public class RangeDrawer : PropertyDrawer {
RangeAttribute
public class RangeAttribute : PropertyAttribute {
public float min;
public float max;
public RangeAttribute (float min, float max) {
this.min = min;
this.max = max;
}
}
RangeDrawer
[CustomPropertyDrawer (typeof (RangeAttribute))]
public class RangeDrawer : PropertyDrawer {
RangeAttribute
public class RangeAttribute : PropertyAttribute {
public float min;
public float max;
public RangeAttribute (float min, float max) {
this.min = min;
this.max = max;
}
}
RangeDrawer
[CustomPropertyDrawer (typeof (RangeAttribute))]
public class RangeDrawer : PropertyDrawer {
Author Once,
Deploy Everywhere
Enemy
Player
Missile
CamBehaviour
[Range ( , )]
Ingredient
[Serializable]
public class Ingredient {
public string name;
public int amount;
}
IngredientDrawer
[CustomPropertyDrawer (typeof (Ingredient))]
public class IngredientDrawer : PropertyDrawer {
Ingredient
[Serializable]
public class Ingredient {
public string name;
public int amount;
}
IngredientDrawer
[CustomPropertyDrawer (typeof (Ingredient))]
public class IngredientDrawer : PropertyDrawer {
Custom controls
with
SerializedProperties
Dial?
2D Slider?
SpeedPopupAttribute
public class SpeedPopupAttribute : PropertyAttribute { }
SpeedPopupDrawer
[CustomPropertyDrawer (typeof (SpeedPopupAttribute))]
public class SpeedPopupDrawer : PropertyDrawer {
enum SpeedOption { Slow, Fast }
public override void OnGUI ( Rect position,
SerializedProperty property,
GUIContent label) {
EditorGUI.BeginChangeCheck ();
if (EditorGUI.EndChangeCheck ())
property.boolValue = (enumValue == SpeedOption.Fast ? true : false);
SpeedOption enumValue =
(property.boolValue == true ? SpeedOption.Fast : SpeedOption.Slow);
EditorGUI.EndProperty ();
SpeedPopupAttribute
public class SpeedPopupAttribute : PropertyAttribute { }
SpeedPopupDrawer
[SpeedPopup]
bool isFast
EditorGUI.BeginChangeCheck ();
if (EditorGUI.EndChangeCheck ())
property.boolValue = (enumValue == SpeedOption.Fast ? true : false);
SpeedOption enumValue =
(property.boolValue == true ? SpeedOption.Fast : SpeedOption.Slow);
EditorGUI.EndProperty ();
SpeedPopupAttribute
public class SpeedPopupAttribute : PropertyAttribute { }
SpeedPopupDrawer
[CustomPropertyDrawer (typeof (SpeedPopupAttribute))]
public class SpeedPopupDrawer : PropertyDrawer {
enum SpeedOption { Slow, Fast }
public override void OnGUI ( Rect position,
SerializedProperty property,
GUIContent label) {
EditorGUI.BeginChangeCheck ();
if (EditorGUI.EndChangeCheck ())
property.boolValue = (enumValue == SpeedOption.Fast ? true : false);
SpeedOption enumValue =
(property.boolValue == true ? SpeedOption.Fast : SpeedOption.Slow);
EditorGUI.EndProperty ();
SpeedPopupAttribute
public class SpeedPopupAttribute : PropertyAttribute { }
SpeedPopupDrawer
[CustomPropertyDrawer (typeof (SpeedPopupAttribute))]
public class SpeedPopupDrawer : PropertyDrawer {
enum SpeedOption { Slow, Fast }
public override void OnGUI ( Rect position,
SerializedProperty property,
GUIContent label) {
EditorGUI.BeginChangeCheck ();
if (EditorGUI.EndChangeCheck ())
property.boolValue = (enumValue == SpeedOption.Fast ? true : false);
SpeedOption enumValue =
(property.boolValue == true ? SpeedOption.Fast : SpeedOption.Slow);
EditorGUI.EndProperty ();
SpeedPopupAttribute
public class SpeedPopupAttribute : PropertyAttribute { }
SpeedPopupDrawer
[CustomPropertyDrawer (typeof (SpeedPopupAttribute))]
public class SpeedPopupDrawer : PropertyDrawer {
enum SpeedOption { Slow, Fast }
public override void OnGUI ( Rect position,
SerializedProperty property,
GUIContent label) {
EditorGUI.BeginChangeCheck ();
if (EditorGUI.EndChangeCheck ())
property.boolValue = (enumValue == SpeedOption.Fast ? true : false);
SpeedOption enumValue =
(property.boolValue == true ? SpeedOption.Fast : SpeedOption.Slow);
EditorGUI.EndProperty ();
SpeedPopupAttribute
public class SpeedPopupAttribute : PropertyAttribute { }
SpeedPopupDrawer
[CustomPropertyDrawer (typeof (SpeedPopupAttribute))]
public class SpeedPopupDrawer : PropertyDrawer {
enum SpeedOption { Slow, Fast }
public override void OnGUI ( Rect position,
SerializedProperty property,
GUIContent label) {
EditorGUI.BeginChangeCheck ();
if (EditorGUI.EndChangeCheck ())
property.boolValue = (enumValue == SpeedOption.Fast ? true : false);
SpeedOption enumValue =
(property.boolValue == true ? SpeedOption.Fast : SpeedOption.Slow);
EditorGUI.EndProperty ();
BAD:
newValue = Control (oldValue);
if (newValue != oldValue)
myProperty.value = newValue;
GOOD:
BeginChangeCheck ();
value = Control (value);
if (EndChangeCheck ())
myProperty.value = value;
SpeedPopupAttribute
public class SpeedPopupAttribute : PropertyAttribute { }
SpeedPopupDrawer
[CustomPropertyDrawer (typeof (SpeedPopupAttribute))]
public class SpeedPopupDrawer : PropertyDrawer {
enum SpeedOption { Slow, Fast }
public override void OnGUI ( Rect position,
SerializedProperty property,
GUIContent label) {
EditorGUI.BeginChangeCheck ();
if (EditorGUI.EndChangeCheck ())
property.boolValue = (enumValue == SpeedOption.Fast ? true : false);
SpeedOption enumValue =
(property.boolValue == true ? SpeedOption.Fast : SpeedOption.Slow);
EditorGUI.EndProperty ();
SpeedPopupAttribute
public class SpeedPopupAttribute : PropertyAttribute { }
SpeedPopupDrawer
[CustomPropertyDrawer (typeof (SpeedPopupAttribute))]
public class SpeedPopupDrawer : PropertyDrawer {
enum SpeedOption { Slow, Fast }
public override void OnGUI ( Rect position,
SerializedProperty property,
GUIContent label) {
EditorGUI.BeginChangeCheck ();
if (EditorGUI.EndChangeCheck ())
property.boolValue = (enumValue == SpeedOption.Fast ? true : false);
SpeedOption enumValue =
(property.boolValue == true ? SpeedOption.Fast : SpeedOption.Slow);
EditorGUI.EndProperty ();
SpeedPopupAttribute
public class SpeedPopupAttribute : PropertyAttribute { }
SpeedPopupDrawer
[CustomPropertyDrawer (typeof (SpeedPopupAttribute))]
public class SpeedPopupDrawer : PropertyDrawer {
enum SpeedOption { Slow, Fast }
public override void OnGUI ( Rect position,
SerializedProperty property,
GUIContent label) {
EditorGUI.BeginChangeCheck ();
if (EditorGUI.EndChangeCheck ())
property.boolValue = (enumValue == SpeedOption.Fast ? true : false);
SpeedOption enumValue =
(property.boolValue == true ? SpeedOption.Fast : SpeedOption.Slow);
EditorGUI.EndProperty ();
Key takeaways
Key takeaways
Key takeaways
BeginChangeCheck / EndChangeCheck
Key takeaways
BeginChangeCheck / EndChangeCheck
Completely custom
controls
Other
editor scripting
OnSceneGUI
OnSceneGUI
OnSceneGUI
OnSceneGUI
OnSceneGUI
OnSceneGUI
EditorWindows
EditorWindows
EditorWindows
AwesomeEditorWindow
using UnityEngine;
using UnityEditor;
public class AwesomeEditorWindow : EditorWindow {
[MenuItem ("Window/Awesome Window")]
public static void ShowAwesomeEditorWindow () {
GetWindow <AwesomeEditorWindow> ();
}
public void OnGUI () {
// Custom GUI
}
}
AwesomeEditorWindow
using UnityEngine;
using UnityEditor;
public class AwesomeEditorWindow : EditorWindow {
[MenuItem ("Window/Awesome Window")]
public static void ShowAwesomeEditorWindow () {
GetWindow <AwesomeEditorWindow> ();
}
public void OnGUI () {
// Custom GUI
}
}
AwesomeEditorWindow
using UnityEngine;
using UnityEditor;
public class AwesomeEditorWindow : EditorWindow {
[MenuItem ("Window/Awesome Window")]
public static void ShowAwesomeEditorWindow () {
GetWindow <AwesomeEditorWindow> ();
}
public void OnGUI () {
// Custom GUI
}
}
AwesomeEditorWindow
using UnityEngine;
using UnityEditor;
public class AwesomeEditorWindow : EditorWindow {
[MenuItem ("Window/Awesome Window")]
public static void ShowAwesomeEditorWindow () {
GetWindow <AwesomeEditorWindow> ();
}
public void OnGUI () {
// Custom GUI
}
}
Questions?
Lots of helpful people on the forums,
UnityAnswers and the Unity IRC channel.
If no help, PM me with link to your post.
(runevision in the forums)
twitter
@runevisioncom