I keep going around and around with this property drawer I have been working on. I have it working the way I want but I cannot stop it from overlapping anything that comes after it in the inspector. I found one person in the forums that overrode GetPropertyHeight but I couldn’t get that to work. Here is a simplified version of the code I am using…
SampleClass.js
#pragma strict
class SampleClass extends Object{
var first : float;
var second : float;
var third : float;
}
SampleDrawer.js
#pragma strict
@CustomPropertyDrawer (SampleClass)
class SampleDrawer extends PropertyDrawer {
var min : float = 0;
var max : float = 1;
var unfolded : boolean;
// Draw the property inside the given rect
function OnGUI (position : Rect, property : SerializedProperty, label : GUIContent) {
var first : SerializedProperty = property.FindPropertyRelative ("first");
var second : SerializedProperty = property.FindPropertyRelative ("second");
var third : SerializedProperty = property.FindPropertyRelative ("third");
// Using BeginProperty / EndProperty on the parent property means that
// prefab override logic works on the entire property.
// Draw label
EditorGUI.BeginProperty (position, label, property);
unfolded = EditorGUI.Foldout(position,unfolded,label);
if(unfolded){
EditorGUI.Slider (new Rect(position.x,position.y+20,position.width,position.height),first, min, max, GUIContent("first"));
EditorGUI.Slider (new Rect(position.x,position.y+40,position.width,position.height),second, min, max, GUIContent("second"));
EditorGUI.Slider (new Rect(position.x,position.y+60,position.width,position.height),third, min, max, GUIContent("third"));
}
EditorGUI.EndProperty ();
}
}
here is a pic of what it looks like
Keeping the class serializable so it can fold and unfold would be nice, but if i can stop the overlap problem I could live without it. Anyone have any thoughts? THANKS
This is because you are not using the layout version of the editor GUI controls. If you want to do this then you could use GUILayout.Space with sufficient spacing (specified in pixels). Though I would recommend just using EditorGUILayout instead of EditorGUI
I don’t think GUILayout has anything to do with this.
Can you show the version of the code you tried with GetPropertyHeight implemented? It’s supposed to handle stuff like this, I think perhaps you implemented it wrongly.
Yes, you are right. I am incorrectly confusing them with the way in which PlayMaker has implemented their property drawers which just use GUILayout. The solution is literally to just override GetPropertyHeight. Sorry for any confusion!
@numberkruncher Thanks for the quick reply anyway I really appreciate it!
Richard, it seems like a few others have solved the problem with overrriding GetPropertyHeight. I found this very succinct way to do it but I am having trouble switching the code over to Javascript because of the usage of “base” Do you know if there is any way for JS to refer back to the original function like this? Here is the code…
Hey thanks numberkruncher that was what I needed. Unfortunately I think I am implementing something incorrectly because the override of the GetPropertyHeight function isn’t doing anything. Here is the SampleDrawer.js script as I have it written now…
#pragma strict
@CustomPropertyDrawer (SampleClass)
class SampleDrawer extends PropertyDrawer {
var min : float = 0;
var max : float = 1;
var unfolded : boolean;
// Draw the property inside the given rect
function OnGUI (position : Rect, property : SerializedProperty, label : GUIContent) {
var first : SerializedProperty = property.FindPropertyRelative ("first");
var second : SerializedProperty = property.FindPropertyRelative ("second");
var third : SerializedProperty = property.FindPropertyRelative ("third");
// Using BeginProperty / EndProperty on the parent property means that
// prefab override logic works on the entire property.
// Draw label
EditorGUI.BeginProperty (position, label, property);
unfolded = EditorGUI.Foldout(position,unfolded,label);
if(unfolded){
EditorGUI.Slider (new Rect(position.x,position.y+20,position.width,position.height),first, min, max, GUIContent("first"));
EditorGUI.Slider (new Rect(position.x,position.y+40,position.width,position.height),second, min, max, GUIContent("second"));
EditorGUI.Slider (new Rect(position.x,position.y+60,position.width,position.height),third, min, max, GUIContent("third"));
}
EditorGUI.EndProperty ();
}
//override this function to add space below the new property drawer
function GetPropertyHeight(property, label) {
var extraHeight = 100;
return super.GetPropertyHeight(property, label) + extraHeight;
}
}
I am clearly in way over my head here because I don’t really know why this will or won’t work
Do I need to call the new GetPropertyHeight function inside my OnGUI to get it to work maybe?
Stupid question (maybe) but why use PropertyDrawer over Editor? GUILayout and EditorGUILayout sounds too big of a feature to skip. What does a PropertyDrawer gives over an Editor?
i started with propertydrawer in the past few days, and it was a frustrating experience due to lack of tutorials/topics on it…specially the overlapping thingi … anyway…
that’s not a stupid question…i personally need enlightenment on this by someone…
i tried using GUILayout/EditorGUILayout on list of classes like (List or class[ ]) but they didn’t seem to work with me ( no changes on unity GUI) and am not sure if i did something wrong… but i found propertydrawer works fine with lists and arrays regardless where they are…
You can implement a custom property drawer to provide a custom user interface for one single field when using the default inspector. In many cases this avoids needing to implement an entire inspector. One of the biggest advantages with custom property drawers is that they can be associated with a custom attribute allowing additional context to be passed into the custom drawer.
For example, you could associate a custom property drawer with the attribute “HeroPowerFilter”. Your property drawer could then display a popup interface where options are filtered as specified.
public class Hero : MonoBehaviour {
[HeroPowerFilter(PowerSelectionFilter.SuperPower)]
public int power;
[HeroPowerFilter(PowerSelectionFilter.BasicPower)]
public int basicPower;
[Range(0, 1)]
public float speed;
public Vector2 direction;
}
Note that you can take advantage of custom property drawers within regular Editor’s and EditorWindow’s by using EditorGUI.PropertyField.
The download includes a user guide (Support/User Guide.pdf) and more importantly the API Reference (Support/API Reference.chm) where the latter includes various usage examples.
I’m not sure why you say “passing an attribute” is a feature of PropertyDrawer. I pass attributes (multiples) around all the time. Often, a single attribute is not enough. I also read somewhere that PD are limited to a single Attribute. (Weird?)
Frankly, it feels like every Inspector “system” has its pros and cons. Being unable to use GUILayout in PD is an obvious con.
As for using an “Inspector-in-EditorWindow”… I guess I wrote my own.
The main benefit of PropertyDrawer that I’ve seen is that you can define how a custom type is represented in the Inspector view, and Unity will then present it that way regardless of which scripts the type is used in.
For example I made a class to contain some Lua script text (just a Serializable class with a public string field), and a PropertyDrawer for it that customizes the presentation, and now any instance of this LuaScript class in a MonoBehaviour or ScriptableObject gets presented this way, without needing one Editor class per MonoBehaviour. It’s a bit like how Unity has a specific way to present Color fields - including a pop-out selector window - without scripts that use Colors needing to worry about dealing with the Inspector.
So it’s a field-level customization rather than a script-level customization, and it’s probably most appealing to library authors.
I guess I also ended up writing my own system that does just that… But with support for GUILayout/EditorGUILayout. But on top of having it per “type”, I can also flag it per “field”.
In PlayMaker you are able to use GUILayout in their variation of custom property drawers which are known as “ObjectPropertyDrawer”. You can find out more about these in their documentation: