您最多选择25个主题
主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
157 行
4.8 KiB
157 行
4.8 KiB
using UnityEditor;
|
|
using UnityEditorInternal;
|
|
using UnityEngine;
|
|
using static UnityEditor.EditorGUI;
|
|
|
|
namespace UOP1.StateMachine.Editor
|
|
{
|
|
internal class TransitionDisplayHelper
|
|
{
|
|
internal SerializedTransition SerializedTransition { get; }
|
|
private readonly ReorderableList _reorderableList;
|
|
private readonly TransitionTableEditor _editor;
|
|
|
|
internal TransitionDisplayHelper(SerializedTransition serializedTransition, TransitionTableEditor editor)
|
|
{
|
|
SerializedTransition = serializedTransition;
|
|
_reorderableList = new ReorderableList(SerializedTransition.Transition.serializedObject, SerializedTransition.Conditions, true, false, true, true);
|
|
SetupConditionsList(_reorderableList);
|
|
_editor = editor;
|
|
}
|
|
|
|
internal bool Display(ref Rect position)
|
|
{
|
|
var rect = position;
|
|
float listHeight = _reorderableList.GetHeight();
|
|
float singleLineHeight = EditorGUIUtility.singleLineHeight;
|
|
|
|
// Reserve space
|
|
{
|
|
rect.height = singleLineHeight + 10 + listHeight;
|
|
GUILayoutUtility.GetRect(rect.width, rect.height);
|
|
position.y += rect.height + 5;
|
|
}
|
|
|
|
// Background
|
|
{
|
|
rect.x += 5;
|
|
rect.width -= 10;
|
|
rect.height -= listHeight;
|
|
DrawRect(rect, ContentStyle.DarkGray);
|
|
}
|
|
|
|
// Transition Header
|
|
{
|
|
rect.x += 3;
|
|
LabelField(rect, "To");
|
|
|
|
rect.x += 20;
|
|
LabelField(rect, SerializedTransition.ToState.objectReferenceValue.name, EditorStyles.boldLabel);
|
|
}
|
|
|
|
|
|
// Buttons
|
|
{
|
|
bool Button(Rect pos, string icon) => GUI.Button(pos, EditorGUIUtility.IconContent(icon));
|
|
|
|
var buttonRect = new Rect(
|
|
x: rect.width - 90,
|
|
y: rect.y + 5,
|
|
width: 30,
|
|
height: 18);
|
|
|
|
// Move transition up
|
|
if (Button(buttonRect, "scrollup"))
|
|
if (_editor.ReorderTransition(SerializedTransition, true))
|
|
return true;
|
|
|
|
buttonRect.x += 35;
|
|
|
|
// Move transition down
|
|
if (Button(buttonRect, "scrolldown"))
|
|
if (_editor.ReorderTransition(SerializedTransition, false))
|
|
return true;
|
|
|
|
buttonRect.x += 35;
|
|
|
|
// Remove transition
|
|
if (Button(buttonRect, "Toolbar Minus"))
|
|
{
|
|
_editor.RemoveTransition(SerializedTransition.Index);
|
|
return true;
|
|
}
|
|
}
|
|
|
|
|
|
rect.x = position.x + 5;
|
|
rect.y += rect.height;
|
|
rect.width = position.width - 10;
|
|
rect.height = listHeight;
|
|
|
|
// Display conditions
|
|
_reorderableList.DoList(rect);
|
|
|
|
return false;
|
|
}
|
|
|
|
private static void SetupConditionsList(ReorderableList reorderableList)
|
|
{
|
|
reorderableList.elementHeight *= 2.3f;
|
|
reorderableList.headerHeight = 1f;
|
|
reorderableList.onAddCallback += list =>
|
|
{
|
|
int count = list.count;
|
|
list.serializedProperty.InsertArrayElementAtIndex(count);
|
|
var prop = list.serializedProperty.GetArrayElementAtIndex(count);
|
|
prop.FindPropertyRelative("Condition").objectReferenceValue = null;
|
|
prop.FindPropertyRelative("ExpectedResult").enumValueIndex = 0;
|
|
prop.FindPropertyRelative("Operator").enumValueIndex = 0;
|
|
};
|
|
|
|
reorderableList.drawElementCallback += (Rect rect, int index, bool isActive, bool isFocused) =>
|
|
{
|
|
var prop = reorderableList.serializedProperty.GetArrayElementAtIndex(index);
|
|
rect = new Rect(rect.x, rect.y + 2.5f, rect.width, EditorGUIUtility.singleLineHeight);
|
|
var condition = prop.FindPropertyRelative("Condition");
|
|
|
|
// Draw the picker for the Condition SO
|
|
if (condition.objectReferenceValue != null)
|
|
{
|
|
string label = condition.objectReferenceValue.name;
|
|
GUI.Label(rect, "If");
|
|
var r = rect;
|
|
r.x += 20;
|
|
r.width = 35;
|
|
EditorGUI.PropertyField(r, condition, GUIContent.none);
|
|
r.x += 40;
|
|
r.width = rect.width - 120;
|
|
GUI.Label(r, label, EditorStyles.boldLabel);
|
|
}
|
|
else
|
|
{
|
|
EditorGUI.PropertyField(new Rect(rect.x, rect.y, 150, rect.height), condition, GUIContent.none);
|
|
}
|
|
|
|
// Draw the boolean value expected by the condition (i.e. "Is True", "Is False")
|
|
EditorGUI.LabelField(new Rect(rect.x + rect.width - 80, rect.y, 20, rect.height), "Is");
|
|
EditorGUI.PropertyField(new Rect(rect.x + rect.width - 60, rect.y, 60, rect.height), prop.FindPropertyRelative("ExpectedResult"), GUIContent.none);
|
|
|
|
// Only display the logic condition if there's another one after this
|
|
if (index < reorderableList.count - 1)
|
|
EditorGUI.PropertyField(new Rect(rect.x + 20, rect.y + EditorGUIUtility.singleLineHeight + 5, 60, rect.height), prop.FindPropertyRelative("Operator"), GUIContent.none);
|
|
};
|
|
|
|
reorderableList.onChangedCallback += list => list.serializedProperty.serializedObject.ApplyModifiedProperties();
|
|
reorderableList.drawElementBackgroundCallback += (Rect rect, int index, bool isActive, bool isFocused) =>
|
|
{
|
|
if (isFocused)
|
|
EditorGUI.DrawRect(rect, ContentStyle.Focused);
|
|
|
|
if (index % 2 != 0)
|
|
EditorGUI.DrawRect(rect, ContentStyle.ZebraDark);
|
|
else
|
|
EditorGUI.DrawRect(rect, ContentStyle.ZebraLight);
|
|
};
|
|
}
|
|
}
|
|
}
|