Danro/Assets/Scripts/Editor/SequenceActionDrawer.cs

112 lines
4.6 KiB
C#

using System;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using RR.Common.Behaviour;
namespace RR.Common.InspectorOverrides
{
[CustomPropertyDrawer(typeof(SequenceAction), true)]
public class SequenceActionDrawer : PropertyDrawer
{
private static readonly Dictionary<string, Type> ActionTypes = new()
{
{ "Задержка", typeof(WaitAction) },
{ "Удалить объект", typeof(DeleteGameObjectAction) },
{ "Поведение игрока/Заморозить игрока", typeof(FreezePlayerAction) },
{ "Поведение игрока/Разморозить игрока", typeof(UnfreezePlayerAction) },
{ "Поведение игрока/Телепортировать игрока", typeof(TeleportPlayerAction) },
{ "Поведение диалога/Добавить сообщение", typeof(AddMessageAction) },
{ "Поведение сообщения/Появление сообщения", typeof(MessageAppearAction) },
{ "Поведение сообщения/Исчезновение сообщения", typeof(MessageDisappearAction) },
};
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
EditorGUI.BeginProperty(position, label, property);
// Получаем текущий тип
string currentTypeName = property.managedReferenceValue?.GetType().Name ?? "None";
// Кнопка для выбора типа
Rect buttonRect = new(position.x, position.y, position.width, EditorGUIUtility.singleLineHeight);
if (GUI.Button(buttonRect, $"Тип: {currentTypeName}"))
{
ShowTypeMenu(property);
}
// Отображаем поля выбранного типа
if (property.managedReferenceValue != null)
{
EditorGUI.indentLevel++;
Rect fieldsRect = new(position.x, position.y + EditorGUIUtility.singleLineHeight + 2,
position.width, position.height - EditorGUIUtility.singleLineHeight - 2);
SerializedProperty iterator = property.Copy();
SerializedProperty endProperty = property.GetEndProperty();
bool enterChildren = true;
float yOffset = 0;
while (iterator.NextVisible(enterChildren) && !SerializedProperty.EqualContents(iterator, endProperty))
{
enterChildren = false;
Rect fieldRect = new(fieldsRect.x, fieldsRect.y + yOffset,
fieldsRect.width, EditorGUIUtility.singleLineHeight);
EditorGUI.PropertyField(fieldRect, iterator, true);
yOffset += EditorGUIUtility.singleLineHeight + 2;
}
EditorGUI.indentLevel--;
}
EditorGUI.EndProperty();
}
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
float height = EditorGUIUtility.singleLineHeight;
if (property.managedReferenceValue == null) return height + 4;
SerializedProperty iterator = property.Copy();
SerializedProperty endProperty = property.GetEndProperty();
bool enterChildren = true;
while (iterator.NextVisible(enterChildren) && !SerializedProperty.EqualContents(iterator, endProperty))
{
enterChildren = false;
height += EditorGUIUtility.singleLineHeight + 2;
}
return height + 4;
}
private static void ShowTypeMenu(SerializedProperty property)
{
GenericMenu menu = new();
menu.AddItem(new GUIContent("None (Пусто)"), false, () =>
{
property.managedReferenceValue = null;
property.serializedObject.ApplyModifiedProperties();
});
menu.AddSeparator("");
foreach ((string key, Type type) in ActionTypes)
{
menu.AddItem(new GUIContent(key), false, () =>
{
property.managedReferenceValue = Activator.CreateInstance(type);
property.serializedObject.ApplyModifiedProperties();
});
}
menu.ShowAsContext();
}
}
}