- Home /
How to create custom editor for a class contained within another class
Hey Guys,
I have a scriptable object which holds another custom class
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class TrickStack: ScriptableObject
{
public Trick spinLeft;
public Trick spinRight;
public Trick corkScrewLeft;
public Trick corkScrewRight;
public Trick special01;
}
[System.Serializable]
public class Trick
{
public TrickType type = TrickType.oneShot;
public AnimationClip startClip;
[HideInInspector]
public float startLength;
public AnimationClip holdClip;
[HideInInspector]
public float holdLength;
public AnimationClip endClip;
[HideInInspector]
public float endLength;
}
public enum TrickType
{
oneShot,
stackable,
hold,
}
My best guess at a custom trick editor
using UnityEditor;
using System.Collections;
using UnityEngine;
[CustomEditor(typeof(Trick))]
public class TrickEditor : Editor
{
Trick t;
public override void OnInspectorGUI ()
{
t = (Trick)target;
//do some stuff
}
}
I want to write for Trick as it will be used in multiple places and changing a custom editor for TrickStack everytime a new trick is added would be a pain in the ass. The above gets an error "Scripts/Editor/TrickEditor.cs(12,28): error CS0030: Cannot convert type UnityEngine.Object' to
Trick'"
Answer by WPCJack · Jul 09, 2013 at 04:09 AM
In case anyone else is looking for a neat way to do this. The new property drawers are the bomb. Now "Trick" always appears tastily.
using UnityEngine;
using UnityEditor;
[CustomPropertyDrawer (typeof(Trick))]
public class TrickPropertyDrawer : PropertyDrawer
{
private int rows;
public override void OnGUI (Rect pos, SerializedProperty prop, GUIContent label)
{
SerializedProperty type = prop.FindPropertyRelative ("type");
SerializedProperty startClip = prop.FindPropertyRelative ("startClip");
SerializedProperty startLength = prop.FindPropertyRelative ("startLength");
SerializedProperty holdClip = prop.FindPropertyRelative ("holdClip");
SerializedProperty holdLength = prop.FindPropertyRelative ("holdLength");
SerializedProperty endClip = prop.FindPropertyRelative ("endClip");
SerializedProperty endLength = prop.FindPropertyRelative ("endLength");
EditorGUI.LabelField (
new Rect (pos.x, pos.y, pos.width, pos.height),
label.text);
GUIContent guiType = new GUIContent ("Type");
EditorGUI.PropertyField (
new Rect (pos.x, pos.y + 20, pos.width, pos.height),
type, guiType);
GUIContent guiClip = new GUIContent ("Clip");
if (type.enumValueIndex != 2)
{
rows = 4;
EditorGUI.PropertyField (
new Rect (pos.x, pos.y + 40, pos.width, pos.height),
startClip, guiClip);
if (startClip.objectReferenceValue != null)
{
AnimationClip clip = (AnimationClip)startClip.objectReferenceValue;
startLength.floatValue = clip.length;
}
}
else
{
rows = 7;
guiClip = new GUIContent ("Start Clip");
EditorGUI.PropertyField (
new Rect (pos.x, pos.y + 40, pos.width, pos.height),
startClip, guiClip);
if (startClip.objectReferenceValue != null)
{
AnimationClip clip = (AnimationClip)startClip.objectReferenceValue;
startLength.floatValue = clip.length;
}
guiClip = new GUIContent ("Hold Clip");
EditorGUI.PropertyField (
new Rect (pos.x, pos.y + 60, pos.width, pos.height),
holdClip, guiClip);
if (holdClip.objectReferenceValue != null)
{
AnimationClip clip = (AnimationClip)holdClip.objectReferenceValue;
holdLength.floatValue = clip.length;
}
guiClip = new GUIContent ("End Clip");
EditorGUI.PropertyField (
new Rect (pos.x, pos.y + 80, pos.width, pos.height),
endClip, guiClip);
if (endClip.objectReferenceValue != null)
{
AnimationClip clip = (AnimationClip)endClip.objectReferenceValue;
endLength.floatValue = clip.length;
}
}
}
public override float GetPropertyHeight (SerializedProperty prop,
GUIContent label) {
return base.GetPropertyHeight (prop, label) * rows;
}
}
Answer by Jamora · Jul 08, 2013 at 07:17 AM
I'm not sure if I understood your question... but you can double click (during runtime) on the field in the inspector of the MonoBehaviour that contains TrickShot to open the contents for editing. If that's not enough, then just create a custom editor for the TrickStack class and add your required inspectionality.
Answer by ThomasBowker · Jul 08, 2013 at 08:39 AM
Hi Jack!
I would make a public static function in Trick to handle the inspector.
#if UNITY_EDITOR
using UnityEditor;
#endif
[System.Serializable]
public class Trick
{
// Variables
#if UNITY_EDITOR
public static Trick DoInspector(Trick a_Trick)
{
// Do inspector code on a_Trick here
return a_Trick;
}
#endif
}
Then create an inspector for TrickStack that calls Trick.DoInspector()
Your answer
Follow this Question
Related Questions
Custom Inspector doesn't show changes immediatley 2 Answers
Drag from custom editor ObjectField 0 Answers
Calling OnValidate on a ScriptableObject with a list of ScriptableObjects 1 Answer
[Custom Editor] MonoBehaviour vs Scriptable Object 0 Answers
Object field not working in custom editor for scriptable object? 0 Answers