211 lines
8.8 KiB
C#
211 lines
8.8 KiB
C#
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using UnityEditor;
|
|
using System;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
using MBT;
|
|
|
|
namespace MBTEditor
|
|
{
|
|
[CustomEditor(typeof(Blackboard))]
|
|
public class BlackboardEditor : Editor
|
|
{
|
|
const double CONSTANT_REPAINT_INTERVAL = 0.5d;
|
|
|
|
readonly string[] varOptions = new string[]{"Delete"};
|
|
SerializedProperty variables;
|
|
SerializedProperty masterBlackboardProperty;
|
|
GUIStyle popupStyle;
|
|
string newVariableKey = "";
|
|
string[] variableTypesNames = new string[0];
|
|
Type[] variableTypes = new Type[0];
|
|
int selectedVariableType = 0;
|
|
Blackboard blackboard;
|
|
GameObject blackboardGameObject;
|
|
bool showVariables = true;
|
|
private double lastRepaint;
|
|
|
|
void OnEnable()
|
|
{
|
|
// Set hide flags in case object was duplicated or turned into prefab
|
|
if (target != null)
|
|
{
|
|
Blackboard bb = (Blackboard) target;
|
|
// Sample one variable and check if its hidden. Hide all varialbes if sample is visible.
|
|
if (bb.TryGetComponent<BlackboardVariable>(out BlackboardVariable bv) && bv.hideFlags != HideFlags.HideInInspector)
|
|
{
|
|
BlackboardVariable[] vars = bb.GetComponents<BlackboardVariable>();
|
|
for (int i = 0; i < vars.Length; i++)
|
|
{
|
|
vars[i].hideFlags = HideFlags.HideInInspector;
|
|
}
|
|
}
|
|
}
|
|
// Init
|
|
variables = serializedObject.FindProperty("variables");
|
|
masterBlackboardProperty = serializedObject.FindProperty("masterBlackboard");
|
|
blackboard = target as Blackboard;
|
|
blackboardGameObject = blackboard.gameObject;
|
|
SetupVariableTypes();
|
|
}
|
|
|
|
void OnDestroy()
|
|
{
|
|
// Remove all variables in case Blackboard was removed
|
|
if (Application.isEditor && (Blackboard)target == null && blackboardGameObject != null)
|
|
{
|
|
// Additional check to avoid errors when exiting playmode
|
|
if (Application.IsPlaying(blackboardGameObject) || blackboardGameObject.GetComponent<Blackboard>() != null)
|
|
{
|
|
return;
|
|
}
|
|
BlackboardVariable[] blackboardVariables = blackboardGameObject.GetComponents<BlackboardVariable>();
|
|
for (int i = 0; i < blackboardVariables.Length; i++)
|
|
{
|
|
Undo.DestroyObjectImmediate(blackboardVariables[i]);
|
|
}
|
|
}
|
|
}
|
|
|
|
public override bool RequiresConstantRepaint()
|
|
{
|
|
return Application.isPlaying && EditorApplication.timeSinceStartup > lastRepaint + CONSTANT_REPAINT_INTERVAL;
|
|
}
|
|
|
|
private void SetupVariableTypes()
|
|
{
|
|
List<Type> types = new List<Type>();
|
|
List<string> names = new List<string>();
|
|
|
|
// Find all types
|
|
foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies())
|
|
{
|
|
IEnumerable<Type> enumerable = assembly.GetTypes()
|
|
.Where(myType => myType.IsClass && !myType.IsAbstract && myType.IsSubclassOf(typeof(BlackboardVariable)));
|
|
foreach (Type type in enumerable)
|
|
{
|
|
names.Add(type.Name);
|
|
types.Add(type);
|
|
}
|
|
}
|
|
variableTypesNames = names.ToArray();
|
|
variableTypes = types.ToArray();
|
|
}
|
|
|
|
public override void OnInspectorGUI()
|
|
{
|
|
// Update repaint timer
|
|
lastRepaint = EditorApplication.timeSinceStartup;
|
|
// Init styles
|
|
if (popupStyle == null) {
|
|
popupStyle = new GUIStyle(GUI.skin.GetStyle("PaneOptions"));
|
|
popupStyle.imagePosition = ImagePosition.ImageOnly;
|
|
popupStyle.margin.top += 3;
|
|
}
|
|
|
|
|
|
EditorGUI.BeginChangeCheck();
|
|
EditorGUILayout.PropertyField(masterBlackboardProperty);
|
|
EditorGUILayout.Space();
|
|
if (EditorGUI.EndChangeCheck()) {
|
|
serializedObject.ApplyModifiedProperties();
|
|
}
|
|
|
|
// Fields used to add variables
|
|
EditorGUILayout.LabelField("Create Variable", EditorStyles.boldLabel);
|
|
EditorGUILayout.Space();
|
|
EditorGUILayout.BeginHorizontal();
|
|
GUILayout.Label("Key", GUILayout.MaxWidth(80));
|
|
newVariableKey = EditorGUILayout.TextField(newVariableKey);
|
|
EditorGUILayout.EndHorizontal();
|
|
EditorGUILayout.BeginHorizontal();
|
|
GUILayout.Label("Type", GUILayout.MaxWidth(80));
|
|
selectedVariableType = EditorGUILayout.Popup(selectedVariableType, variableTypesNames);
|
|
GUI.SetNextControlName("AddButton");
|
|
if (GUILayout.Button("Add", EditorStyles.miniButton)) {
|
|
CreateVariableAndResetInput();
|
|
}
|
|
EditorGUILayout.EndHorizontal();
|
|
EditorGUILayout.Space();
|
|
|
|
// DrawDefaultInspector();
|
|
// EditorGUILayout.Space();
|
|
|
|
// serializedObject.Update();
|
|
// EditorGUI.BeginChangeCheck();
|
|
showVariables = EditorGUILayout.BeginFoldoutHeaderGroup(showVariables, "Variables");
|
|
if(showVariables){
|
|
SerializedProperty vars = variables.Copy();
|
|
if (vars.isArray) {
|
|
// xxx: Why this line existed? Why EventType.DragPerform is not allowed here? (maybe BeginChangeCheck)
|
|
// if (vars.isArray && Event.current.type != EventType.DragPerform) {
|
|
for (int i = 0; i < vars.arraySize; i++)
|
|
{
|
|
EditorGUI.BeginChangeCheck();
|
|
int popupOption = -1;
|
|
SerializedProperty serializedV = vars.GetArrayElementAtIndex(i);
|
|
SerializedObject serializedVariable = new SerializedObject(serializedV.objectReferenceValue);
|
|
EditorGUILayout.BeginHorizontal();
|
|
EditorGUILayout.PrefixLabel(
|
|
new GUIContent(serializedVariable.FindProperty("key").stringValue,
|
|
serializedVariable.targetObject.GetType().Name)
|
|
);
|
|
int v = EditorGUILayout.Popup(popupOption, varOptions, popupStyle, GUILayout.MaxWidth(20));
|
|
EditorGUILayout.PropertyField(serializedVariable.FindProperty("val"), GUIContent.none);
|
|
EditorGUILayout.EndHorizontal();
|
|
|
|
if (EditorGUI.EndChangeCheck()) {
|
|
serializedVariable.ApplyModifiedProperties();
|
|
}
|
|
// Delete on change
|
|
if (v != popupOption) {
|
|
DeleteVariabe(serializedV.objectReferenceValue as BlackboardVariable);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
EditorGUILayout.EndFoldoutHeaderGroup();
|
|
EditorGUILayout.Space();
|
|
|
|
// if (EditorGUI.EndChangeCheck()) {
|
|
// serializedObject.ApplyModifiedProperties();
|
|
// }
|
|
}
|
|
|
|
private void DeleteVariabe(BlackboardVariable blackboardVariable)
|
|
{
|
|
Undo.RecordObject(blackboard, "Delete Blackboard Variable");
|
|
blackboard.variables.Remove(blackboardVariable);
|
|
Undo.DestroyObjectImmediate(blackboardVariable);
|
|
}
|
|
|
|
private void CreateVariableAndResetInput()
|
|
{
|
|
// Validate field. Key "None" is not allowed.
|
|
if (string.IsNullOrEmpty(newVariableKey) || newVariableKey.Equals("None")) {
|
|
return;
|
|
}
|
|
string k = new string( newVariableKey.ToCharArray().Where(c => !Char.IsWhiteSpace(c)).ToArray() );
|
|
// Check for key duplicates
|
|
for (int i = 0; i < blackboard.variables.Count; i++)
|
|
{
|
|
if (blackboard.variables[i].key == k) {
|
|
Debug.LogWarning("Variable '"+k+"' already exists.");
|
|
return;
|
|
}
|
|
}
|
|
// Add variable
|
|
Undo.RecordObject(blackboard, "Create Blackboard Variable");
|
|
BlackboardVariable var = Undo.AddComponent(blackboard.gameObject, variableTypes[selectedVariableType]) as BlackboardVariable;
|
|
var.hideFlags = HideFlags.HideInInspector;
|
|
var.key = k;
|
|
blackboard.variables.Add(var);
|
|
// Reset field
|
|
newVariableKey = "";
|
|
GUI.FocusControl("Clear");
|
|
}
|
|
}
|
|
}
|