Hi all!
I couldn’t find another thread with the same problem so I figured I would post here.
I wrote a custom property drawer for a Dialogue class. The property is displayed in a scriptableObject called DialogueTree. It is basically a list of nested instances of the Dialogue class.
I finally managed to make everything look good enough, but in the process my scrollbar has disappeared, making the inspector useless.
Anyone has a clue why? Here’s the code for the PropertyDrawer (it’s a bit messy) :
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
[CustomPropertyDrawer(typeof(Dialogue))]
public class DialogueDrawer : PropertyDrawer {
string[] selectionEnumNames = new string[]{"Show dialogue", "Back to entry point", "Back one step", "End"};
bool isRoot;
Rect nameRect;
Rect nameLabelRect;
Rect selectionRect;
Rect selectionLabelRect;
Rect textRect;
Rect textLabelRect;
Rect answersNumberRect;
Rect answersNumberLabelRect;
Rect answersRect;
//Format variables
float line = 17;
float largeLine = 60;
float smallIndent = 75;
float indent = 150;
float largeIndent = 300;
float dialogueHeight = 145;
public override void OnGUI (Rect position, SerializedProperty property, GUIContent label)
{
//dialogueHeight = line*4 + largeLine;
isRoot = property.FindPropertyRelative("isRoot").boolValue;
EditorGUI.BeginProperty(position, label, property);
property.isExpanded = EditorGUI.Foldout(new Rect(position.x, position.y, position.width, line), property.isExpanded, label);
position.y += line;
if (property.isExpanded)
{
if (isRoot)
{
textRect = new Rect(position.x + indent, position.y, largeIndent, largeLine);
textLabelRect = new Rect(position.x, position.y, position.width, line);
position.y += largeLine;
EditorGUI.PrefixLabel(textLabelRect, new GUIContent("Text to show"));
EditorGUI.PropertyField(textRect, property.FindPropertyRelative("text"), GUIContent.none);
}
if (!isRoot)
{
nameRect = new Rect(position.x + indent, position.y, largeIndent, line);
nameLabelRect = new Rect(position.x, position.y, indent, line);
position.y += line;
EditorGUI.PrefixLabel(nameLabelRect, new GUIContent("Answer"));
EditorGUI.PropertyField(nameRect, property.FindPropertyRelative("name"), GUIContent.none);
selectionRect = new Rect(position.x + indent, position.y, indent, line);
selectionLabelRect = new Rect(position.x, position.y, indent, line);
position.y += line;
EditorGUI.PrefixLabel(selectionLabelRect, new GUIContent("Effect"));
property.FindPropertyRelative("selectionResults").intValue = EditorGUI.Popup(selectionRect, property.FindPropertyRelative("selectionResults").intValue, selectionEnumNames);
textRect = new Rect(position.x + indent, position.y, largeIndent, largeLine);
textLabelRect = new Rect(position.x, position.y, position.width, line);
position.y += largeLine;
EditorGUI.PrefixLabel(textLabelRect, new GUIContent("Text to show"));
EditorGUI.PropertyField(textRect, property.FindPropertyRelative("text"), GUIContent.none);
}
answersNumberRect = new Rect(position.x+indent, position.y, indent/2, line);
answersNumberLabelRect = new Rect(position.x, position.y, position.width, line);
position.y += line;
int answersLength = EditorGUI.IntPopup(answersNumberRect, property.FindPropertyRelative("answers").arraySize, new string[] {"0", "1", "2", "3", "4", "5"}, new int[] {0,1,2,3,4,5});
EditorGUI.PrefixLabel(answersNumberLabelRect, new GUIContent("Number of answers"));
answersRect = new Rect(position.x + smallIndent, position.y, largeIndent, line);
position.y += line;
for (int i = 0; i < property.FindPropertyRelative("answers").arraySize; i++) {
string name = property.FindPropertyRelative("answers").GetArrayElementAtIndex(i).FindPropertyRelative("name").stringValue;
if (name == "")
{
name = "Unnamed element";
}
if (property.FindPropertyRelative("answers").GetArrayElementAtIndex(i).isExpanded){
EditorGUI.PropertyField(new Rect(answersRect.x, position.y, answersRect.width, line),
property.FindPropertyRelative("answers").GetArrayElementAtIndex(i), new GUIContent(name));
position.y += GetPropertyHeight(property.FindPropertyRelative("answers").GetArrayElementAtIndex(i));
} else
{
EditorGUI.PropertyField(new Rect(answersRect.x, position.y, answersRect.width, line), property.FindPropertyRelative("answers").GetArrayElementAtIndex(i), new GUIContent(name));
position.y += line;
}
}
EditorGUI.EndProperty();
while (answersLength < property.FindPropertyRelative("answers").arraySize)
{
property.FindPropertyRelative("answers").DeleteArrayElementAtIndex(property.FindPropertyRelative("answers").arraySize-1);
}
while (answersLength > property.FindPropertyRelative("answers").arraySize)
{
property.FindPropertyRelative("answers").InsertArrayElementAtIndex(property.FindPropertyRelative("answers").arraySize);
}
}
}
public float GetPropertyHeight (SerializedProperty property)
{
float height = dialogueHeight;
Queue<SerializedProperty> answers = new Queue<SerializedProperty>();
if (!property.FindPropertyRelative("answers").isExpanded)
return height;
for (int i = 0; i < property.FindPropertyRelative("answers").arraySize; i++) {
answers.Enqueue(property.FindPropertyRelative("answers").GetArrayElementAtIndex(i));
}
while (answers.Count > 0)
{
if (!answers.Peek().isExpanded)
{
height += line;
answers.Dequeue();
}
else
{
for (int i = 0; i < answers.Peek().FindPropertyRelative("answers").arraySize; i++) {
answers.Enqueue(answers.Peek().FindPropertyRelative("answers").GetArrayElementAtIndex(i));
}
height += dialogueHeight;
answers.Dequeue();
}
}
return (height);
}
}
And here’s a picture of the problem:
