Hi, Since I haven’t got any response on the following link, I’m re-posting the problem here at the forums, hoping that somebody point me to the right direction.
I have a class A that inherits from Monobehaviour, with public variables:
publicclass A :MonoBehaviour
{
publicint num;
publicstring s;
}
When you add A component to a gameobject, you can easily modify the variables, since it has its inspector drawn automatically.
But I have another class B
publicclass B :MonoBehaviour
{
publicList<A> vars;
}
Now I want to create a custom editor for B:
[CustomEditor(typeof(B))]
publicBEditor:Editor
{
publicoverridevoidOnInspectorGUI()
{
var t = target as B;
for(int i =0; i < t.vars.Count; i++)
{
// Here I want to DrawDefaultInspector for t.vars[i]
// or in other words the default inspector for an object
// of class A
}
DrawDefaultInspector();
}
}
How do I draw the default inspector of an object inherited from class A, within custom editor of class B?
How can I do this with minimum pain? (Note: I can go reflection, I consider that to be no pain)
Or use Property drawers so you don’t have to fiddle with the list size
//Assets/classA.cs
using UnityEngine;
using System.Collections;
public class classA: MonoBehaviour {
public int someInt;
public string someString;
}
//Assets/classB.cs
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class classB: MonoBehaviour {
public List<classA> myList;
}
//Assets/Editor/DrawA.cs
using UnityEngine;
using UnityEditor;
using System.Collections;
[CustomPropertyDrawer( typeof( classA ) )]
public class DrawA : PropertyDrawer {
public override float GetPropertyHeight ( SerializedProperty property, GUIContent label ) {
return 32; //2 lines of fields
}
public override void OnGUI ( Rect position, SerializedProperty property, GUIContent label ) {
EditorGUI.BeginProperty( position, label, property );
position = EditorGUI.PrefixLabel( position, GUIUtility.GetControlID( FocusType.Passive ), label );
//store current indent and label width
int indent = EditorGUI.indentLevel;
EditorGUI.indentLevel = 0;
float oldWidth = EditorGUIUtility.labelWidth;
EditorGUIUtility.labelWidth = 80;
position.height = 16;
//get reference to the class object
classA theObject = (classA) property.objectReferenceValue;
//adjust position Rect for controls
Rect r = position;
theObject.someInt = EditorGUI.IntField( r, "Some Int", theObject.someInt );
r.y += r.height;
r.x += 80; //text areas dont come with labels, so make your own and offset next control
GUI.Label( r, "Some String" );
r.width -= 80;
theObject.someString = EditorGUI.TextArea( r, theObject.someString );
//reset indent and label width
EditorGUI.indentLevel = indent;
EditorGUIUtility.labelWidth = oldWidth;
EditorGUI.EndProperty();
}
}
This doesn’t give me the field’s correct inspector, it simply gives you the array element presentation of that. It’s no difference from drawing the array itself.
Nah it’s changing how any occurrance of a public variable of type A is drawn.
I just realised i didn’t include a field for assign the actual objects though:
//Assets/Editor/DrawA.cs
using UnityEngine;
using UnityEditor;
using System.Collections;
[CustomPropertyDrawer( typeof( classA ) )]
public class DrawA : PropertyDrawer {
public override float GetPropertyHeight ( SerializedProperty property, GUIContent label ) {
if ( property.objectReferenceValue != null ) return 46; //3 Lines of fields
return 16; //1 line of fields
}
public override void OnGUI ( Rect position, SerializedProperty property, GUIContent label ) {
EditorGUI.BeginProperty( position, label, property );
//position = EditorGUI.PrefixLabel( position, GUIUtility.GetControlID( FocusType.Passive ), label );
//store current indent and label width
int indent = EditorGUI.indentLevel;
EditorGUI.indentLevel = 0;
float oldWidth = EditorGUIUtility.labelWidth;
EditorGUIUtility.labelWidth = 80;
Rect r = position;
r.height = 16;
EditorGUI.PropertyField( r, property );
//get reference to the class object
if ( property.objectReferenceValue != null ) {
classA theObject = (classA) property.objectReferenceValue;
r.x += 60;
r.y += r.height;
theObject.someInt = EditorGUI.IntField( r, "Some Int", theObject.someInt );
r.y += r.height;
GUI.Label( r, "Some String" );
r.x += 80; //text areas dont come with labels, so make your own and offset next control
r.width -= 80;
theObject.someString = EditorGUI.TextArea( r, theObject.someString );
}
//reset indent and label width
EditorGUI.indentLevel = indent;
EditorGUIUtility.labelWidth = oldWidth;
EditorGUI.EndProperty();
}
}