I am total new (I don’t consider my self even beginer) in editor scripting but recently I had to change some standard assets scripts to fit my needs. I saw there property drawers are used in some scripts e.g. waypoint circuit script. Below is that portion of the script.
namespace UnityStandardAssets.Utility.Inspector
{
#if UNITY_EDITOR
[CustomPropertyDrawer(typeof(WaypointCircuit.WaypointList))]
public class WaypointListDrawer : PropertyDrawer
{
private float lineHeight = 18;
private float spacing = 4;
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
EditorGUI.BeginProperty(position, label, property);
float x = position.x;
float y = position.y;
float inspectorWidth = position.width;
// Draw label
// Don't make child fields be indented
var indent = EditorGUI.indentLevel;
EditorGUI.indentLevel = 0;
//var items = property.FindPropertyRelative("itemsGo");
//var titles = new string[] { "Waypoints", "", "", "" };
//var props = new string[] { "waypoints", "^", "v", "-" };
var widths = new float[] { .7f, .1f, .1f, .1f };
float lineHeight = 18;
//bool changedLength = false;
//if (items.arraySize > 0)
//{
// for (int i = 0; i < items.arraySize; i++)
// {
// var item = items.GetArrayElementAtIndex(i);
// float rowX = x;
// for (int n = 0; n < props.Length; ++n)
// {
// float w = widths[n] * inspectorWidth;
// // Calculate rects
// Rect rect = new Rect(rowX, y, w, lineHeight);
// rowX += w;
// if (i == -1)
// {
// EditorGUI.LabelField(rect, titles[n]);
// }
// else
// {
// if (n == 0)
// {
// EditorGUI.ObjectField(rect, item.objectReferenceValue, typeof(GameObject), true);
// }
// else
// {
// if (GUI.Button(rect, props[n]))
// {
// switch (props[n])
// {
// case "-":
// items.DeleteArrayElementAtIndex(i);
// items.DeleteArrayElementAtIndex(i);
// changedLength = true;
// break;
// case "v":
// if (i > 0)
// {
// items.MoveArrayElement(i, i + 1);
// }
// break;
// case "^":
// if (i < items.arraySize - 1)
// {
// items.MoveArrayElement(i, i - 1);
// }
// break;
// }
// }
// }
// }
// }
// y += lineHeight + spacing;
// if (changedLength)
// {
// break;
// }
// }
//}
//else
//{
// // add button
// var addButtonRect = new Rect((x + position.width) - widths[widths.Length - 1] * inspectorWidth, y,
// widths[widths.Length - 1] * inspectorWidth, lineHeight);
// if (GUI.Button(addButtonRect, "+"))
// {
// items.InsertArrayElementAtIndex(items.arraySize);
// }
// y += lineHeight + spacing;
//}
// add all button
var addAllButtonRect = new Rect(x, y, inspectorWidth, lineHeight);
if (GUI.Button(addAllButtonRect, "Assign using all child objects"))
{
var circuit = property.FindPropertyRelative("circuit").objectReferenceValue as WaypointCircuit;
if (circuit.waypointCubePrefab != null && circuit.waypointCubes.Count == 0)
{
var children = new GameObject[circuit.transform.childCount];
for(int i=0; i < circuit.transform.childCount; i++)
{
children *= circuit.transform.GetChild(i).transform.gameObject;*
}
//foreach (Transform child in circuit.transform)
//{
// children[n++] = child;
//}
// Array.Sort(children, new TransformNameComparer());
int n = 0;
circuit.waypointList.itemsGo = new GameObject[children.Length];
for (n = 0; n < children.Length; ++n)
{
circuit.waypointList.itemsGo[n] = children[n].transform.gameObject;
}
circuit.ConvertWaypointsToCubes();
}
else
{
Debug.LogWarning(“Either there are no way points or prefab is null or the Waypoints are already assigned.”);
}
}
y += lineHeight + spacing;
// show/hide cubes button
var showHideCubesButtonRect = new Rect(x, y, inspectorWidth, lineHeight);
if (GUI.Button(showHideCubesButtonRect, “Show/Hide Waypoint Cubes”))
{
var circuit = property.FindPropertyRelative(“circuit”).objectReferenceValue as WaypointCircuit;
circuit.ShowHideCubes();
}
y += lineHeight + spacing;
// show/hide numbers button
var showHideNumbersButtonRect = new Rect(x, y, inspectorWidth, lineHeight);
if (GUI.Button(showHideNumbersButtonRect, “Show/Hide Waypoint Numbers”))
{
var circuit = property.FindPropertyRelative(“circuit”).objectReferenceValue as WaypointCircuit;
circuit.ShowHideWaypointNumbers();
}
y += lineHeight + spacing;
// rename all button
var renameButtonRect = new Rect(x, y, inspectorWidth, lineHeight);
if (GUI.Button(renameButtonRect, “Auto Rename numerically from this order”))
{
var circuit = property.FindPropertyRelative(“circuit”).objectReferenceValue as WaypointCircuit;
int n = 0;
foreach (Transform child in circuit.waypointList.items)
{
child.name = "Waypoint " + (n++).ToString(“000”);
}
}
y += lineHeight + spacing;
// correct Child Objects Rotation button
var correctWaypointsRotationButton = new Rect(x, y, inspectorWidth, lineHeight);
if (GUI.Button(correctWaypointsRotationButton, “Correct WayPoints Rotations”))
{
var circuit = property.FindPropertyRelative(“circuit”).objectReferenceValue as WaypointCircuit;
circuit.MakeWaypointsRotationAlongRoute();
}
y += lineHeight + spacing;
// spawn prefab button
var spawnPrefabButtonRect = new Rect(x, y, inspectorWidth, lineHeight);
if (GUI.Button(spawnPrefabButtonRect, “Spawn Traffic Spawners Along Route”))
{
var circuit = property.FindPropertyRelative(“circuit”).objectReferenceValue as WaypointCircuit;
circuit.SpawnPrefabAlongRoutes();
}
y += lineHeight + spacing;
// destroy mesh renderers button
var destroyMeshRendererButtonRect = new Rect(x, y, inspectorWidth, lineHeight);
if (GUI.Button(destroyMeshRendererButtonRect, “Remove Mesh Renderers from waypoints Permanently”))
{
var circuit = property.FindPropertyRelative(“circuit”).objectReferenceValue as WaypointCircuit;
circuit.DestroyMeshRenderers();
}
y += lineHeight + spacing;
// Set indent back to what it was
EditorGUI.indentLevel = indent;
EditorGUI.EndProperty();
}
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
SerializedProperty items = property.FindPropertyRelative(“items”);
float lineAndSpace = lineHeight + spacing;
return 150 + (items.arraySize * lineAndSpace) + lineAndSpace;
}
// comparer for check distances in ray cast hits
public class TransformNameComparer : IComparer
{
public int Compare(object x, object y)
{
return ((Transform)x).name.CompareTo(((Transform)y).name);
}
}
}
#endif
There I faced similar issue when height was not adjusted properly and I changed the value (You can see there is written 150 near to bottom lines. Increasing this line helped me. As I said, I don’t have much idea of all this but this helped me. And I was basically wanting to have buttons in the inspector so that I could run my monoscript functions in editor mode… For that I found a Free tool BUTTON INSPECTON on unity asset store. You can go through the above example to check how it is adjusting height and using property drawer.
PS : I wanted to put this as comment instead of answer but unity answers did not let me exceed more than 3000 characters so I had to put it as answers.