#if UNITY_EDITOR using System.Linq; using UnityEditor; using UnityEditorInternal; using UnityEngine; namespace Amanotes.Core { [CustomEditor(typeof(DepthSortGroup))] public class DepthSortGroupEditor : Editor { private ReorderableList _list; private const float SeparatorHeight = 8f; private const float RowHeight = 20f; private void OnEnable() { var entriesProp = serializedObject.FindProperty("entries"); _list = new ReorderableList(serializedObject, entriesProp, true, true, true, true); _list.drawHeaderCallback = rect => EditorGUI.LabelField(rect, "Entries (drag renderers adjacent to merge depth; drag in a separator to split)"); _list.elementHeightCallback = index => { var element = entriesProp.GetArrayElementAtIndex(index); var isSeparator = element.FindPropertyRelative("isSeparator").boolValue; return isSeparator ? SeparatorHeight + 4f : RowHeight + 4f; }; _list.drawElementCallback = (rect, index, active, focused) => { var element = entriesProp.GetArrayElementAtIndex(index); var isSeparatorProp = element.FindPropertyRelative("isSeparator"); var rendererProp = element.FindPropertyRelative("renderer"); rect.y += 2f; if (isSeparatorProp.boolValue) { var lineRect = new Rect(rect.x, rect.y + SeparatorHeight * 0.5f, rect.width, 2f); EditorGUI.DrawRect(lineRect, new Color(1f, 0.6f, 0.1f, 0.8f)); return; } var fieldRect = new Rect(rect.x, rect.y, rect.width - 60f, RowHeight); EditorGUI.PropertyField(fieldRect, rendererProp, GUIContent.none); var groupLabelRect = new Rect(rect.xMax - 55f, rect.y, 55f, RowHeight); EditorGUI.LabelField(groupLabelRect, GroupLabelFor(index), EditorStyles.miniLabel); }; _list.onAddDropdownCallback = (buttonRect, list) => { var menu = new GenericMenu(); menu.AddItem(new GUIContent("Renderer"), false, () => { entriesProp.arraySize++; var e = entriesProp.GetArrayElementAtIndex(entriesProp.arraySize - 1); e.FindPropertyRelative("isSeparator").boolValue = false; e.FindPropertyRelative("renderer").objectReferenceValue = null; serializedObject.ApplyModifiedProperties(); }); menu.AddItem(new GUIContent("Separator"), false, () => { entriesProp.arraySize++; var e = entriesProp.GetArrayElementAtIndex(entriesProp.arraySize - 1); e.FindPropertyRelative("isSeparator").boolValue = true; serializedObject.ApplyModifiedProperties(); }); menu.ShowAsContext(); }; } // group index = number of separators-with-content before this row, for the inline label private string GroupLabelFor(int index) { var entriesProp = serializedObject.FindProperty("entries"); var group = 0; var groupHasContent = false; for (var i = 0; i <= index && i < entriesProp.arraySize; i++) { var element = entriesProp.GetArrayElementAtIndex(i); var isSeparator = element.FindPropertyRelative("isSeparator").boolValue; if (isSeparator) { if (groupHasContent) { group++; groupHasContent = false; } continue; } if (i == index) return $"#{group}"; groupHasContent = true; } return $"#{group}"; } public override void OnInspectorGUI() { serializedObject.Update(); var sortingLayerIDProp = serializedObject.FindProperty("sortingLayerID"); var layers = SortingLayer.layers; var names = layers.Select(l => l.name).ToArray(); var currentIndex = System.Array.FindIndex(layers, l => l.id == sortingLayerIDProp.intValue); if (currentIndex < 0) currentIndex = 0; EditorGUI.BeginChangeCheck(); var newIndex = EditorGUILayout.Popup("Sorting Layer", currentIndex, names); if (EditorGUI.EndChangeCheck()) { sortingLayerIDProp.intValue = layers[newIndex].id; } EditorGUILayout.PropertyField(serializedObject.FindProperty("sortIndex")); EditorGUILayout.Space(); _list.DoLayoutList(); serializedObject.ApplyModifiedProperties(); } } } #endif