Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions Assets/KadaXuanwu/UtilityDesigner/Scripts/CategoryPathAttribute.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using System;

namespace KadaXuanwu.UtilityDesigner.Scripts
{
[AttributeUsage(AttributeTargets.Class, Inherited = true, AllowMultiple = false)]
public sealed class CategoryPathAttribute : Attribute
{
public string SubCategoryPath { get; }

public CategoryPathAttribute(string subCategoryPath)
{
SubCategoryPath = subCategoryPath;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,51 +7,68 @@ namespace KadaXuanwu.UtilityDesigner.Scripts.Editor
[CustomEditor(typeof(UtilityDesigner))]
public class UtilityDesignerEditor : UnityEditor.Editor
{
public override void OnInspectorGUI()
private SerializedProperty utilityBehaviour;
private SerializedProperty sceneReferencesObjName;
private SerializedProperty tickRateEvaluation;
private SerializedProperty useUpdateAsTickRateForEvaluation;
private SerializedProperty logEvaluationToFile;
private SerializedProperty tickRateLog;
private SerializedProperty tickRateExecution;
private SerializedProperty useUpdateAsTickRateForExecution;

private void OnEnable()
{
UtilityDesigner utilityDesigner = (UtilityDesigner)target;
utilityBehaviour = serializedObject.FindProperty("utilityBehaviour");
sceneReferencesObjName = serializedObject.FindProperty("sceneReferencesObjName");
tickRateEvaluation = serializedObject.FindProperty("tickRateEvaluation");
useUpdateAsTickRateForEvaluation = serializedObject.FindProperty("useUpdateAsTickRateForEvaluation");
logEvaluationToFile = serializedObject.FindProperty("logEvaluationToFile");
tickRateLog = serializedObject.FindProperty("tickRateLog");
tickRateExecution = serializedObject.FindProperty("tickRateExecution");
useUpdateAsTickRateForExecution = serializedObject.FindProperty("useUpdateAsTickRateForExecution");
}

public override void OnInspectorGUI()
{
serializedObject.Update();

utilityDesigner.utilityBehaviour = (UtilityBehaviour)EditorGUILayout.ObjectField(new GUIContent("Utility Behaviour",
"The behaviour used for this object."),
utilityDesigner.utilityBehaviour, typeof(UtilityBehaviour), true);
utilityDesigner.sceneReferencesObjName = EditorGUILayout.TextField(new GUIContent("Scene Refs Obj Name",
"Name of the GameObject with a SceneReferences component to be used for the action nodes."),
utilityDesigner.sceneReferencesObjName);
EditorGUILayout.PropertyField(utilityBehaviour, new GUIContent("Utility Behaviour",
"The behaviour used for this object."));
EditorGUILayout.PropertyField(sceneReferencesObjName, new GUIContent("Scene Refs Obj Name",
"Name of the GameObject with a SceneReferences component to be used for the action nodes."));

EditorGUILayout.Space();
EditorGUILayout.LabelField("Evaluation", EditorStyles.boldLabel);

if (!utilityDesigner.useUpdateAsTickRateForEvaluation)
utilityDesigner.tickRateEvaluation = EditorGUILayout.Slider(new GUIContent("Tick Rate",
"The tick rate of which the evaluation is updated."),
utilityDesigner.tickRateEvaluation, 0.01f, 1f);
if (!useUpdateAsTickRateForEvaluation.boolValue)
{
EditorGUILayout.Slider(tickRateEvaluation, 0.01f, 1f, new GUIContent("Tick Rate",
"The tick rate of which the evaluation is updated."));
}

utilityDesigner.useUpdateAsTickRateForEvaluation = EditorGUILayout.Toggle(new GUIContent("Use Update As Tick Rate",
"Uses Unity's Update method as tick rate instead."),
utilityDesigner.useUpdateAsTickRateForEvaluation);
EditorGUILayout.PropertyField(useUpdateAsTickRateForEvaluation, new GUIContent("Use Update As Tick Rate",
"Uses Unity's Update method as tick rate instead."));

utilityDesigner.logEvaluationToFile = EditorGUILayout.Toggle(new GUIContent("Log To File",
"Creates a new text file called 'UtilityDesignerLog' in the Assets folder and logs the current stats of the evaluation tab to it. Overrides if it already exists."),
utilityDesigner.logEvaluationToFile);
EditorGUILayout.PropertyField(logEvaluationToFile, new GUIContent("Log To File",
"Creates a new text file called 'UtilityDesignerLog' in the Assets folder and logs the current stats of the evaluation tab to it. Overrides if it already exists."));

if (utilityDesigner.logEvaluationToFile)
utilityDesigner.tickRateLog = EditorGUILayout.Slider(new GUIContent("Logging tick rate",
"The tick rate of which the stats are logged."),
utilityDesigner.tickRateLog, 0.1f, 10f);
if (logEvaluationToFile.boolValue)
{
EditorGUILayout.Slider(tickRateLog, 0.1f, 10f, new GUIContent("Logging tick rate",
"The tick rate of which the stats are logged."));
}

EditorGUILayout.Space();
EditorGUILayout.LabelField("Execution", EditorStyles.boldLabel);

if (!utilityDesigner.useUpdateAsTickRateForExecution)
utilityDesigner.tickRateExecution = EditorGUILayout.Slider(new GUIContent("Tick Rate",
"The tick rate of which the execution is updated."),
utilityDesigner.tickRateExecution, 0.01f, 1f);
if (!useUpdateAsTickRateForExecution.boolValue)
{
EditorGUILayout.Slider(tickRateExecution, 0.01f, 1f, new GUIContent("Tick Rate",
"The tick rate of which the execution is updated."));
}

utilityDesigner.useUpdateAsTickRateForExecution = EditorGUILayout.Toggle(new GUIContent("Use Update As Tick Rate",
"Uses Unity's Update method as tick rate instead."),
utilityDesigner.useUpdateAsTickRateForExecution);
EditorGUILayout.PropertyField(useUpdateAsTickRateForExecution, new GUIContent("Use Update As Tick Rate",
"Uses Unity's Update method as tick rate instead."));

EditorGUILayout.Space();

Expand All @@ -64,7 +81,9 @@ public override void OnInspectorGUI()
GUILayout.FlexibleSpace();
if (GUILayout.Button("Open editor", buttonStyle, GUILayout.Height(22),
GUILayout.Width(EditorGUIUtility.currentViewWidth * 0.6f)))
{
UtilityDesignerEditorWindow.OpenWindow();
}
GUILayout.FlexibleSpace();
EditorGUILayout.EndHorizontal();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using KadaXuanwu.UtilityDesigner.Scripts.Editor;
using KadaXuanwu.UtilityDesigner.Scripts.Execution.Runtime;
using UnityEditor;
Expand All @@ -19,7 +20,7 @@ public class BehaviourTreeView : GraphView
private BehaviourTree _behaviourTree;
private UtilityDesigner _utilityDesigner;
private UtilityDesignerEditorWindow _utilityDesignerEditorWindow;

private NodeSearchWindow _nodeSearchWindow;

public BehaviourTreeView()
{
Expand Down Expand Up @@ -49,6 +50,22 @@ private void OnKeyDown(KeyDownEvent e)
e.StopPropagation();
break;
}
else if (e.keyCode == KeyCode.Space)
{
ShowNodeSearch();
e.StopPropagation();
}
}

private void InitializeNodeSearch()
{
_nodeSearchWindow = ScriptableObject.CreateInstance<NodeSearchWindow>();
_nodeSearchWindow.Initialize(this, _utilityDesignerEditorWindow);
}

private void ShowNodeSearch()
{
SearchWindow.Open(new SearchWindowContext(GUIUtility.GUIToScreenPoint(Event.current.mousePosition)), _nodeSearchWindow);
}

private NodeView FindNodeView(BaseNode node)
Expand All @@ -65,6 +82,8 @@ internal void PopulateView(BehaviourTree tree, UtilityDesigner utilityDesigner,
_utilityDesigner = utilityDesigner;
_utilityDesignerEditorWindow = utilityDesignerEditorWindow;

InitializeNodeSearch();

graphViewChanged -= OnGraphViewChanged;
DeleteElements(graphElements);
graphViewChanged += OnGraphViewChanged;
Expand Down Expand Up @@ -180,34 +199,46 @@ internal void CreateContextualMenu(Vector2 position)
AddItems<DecoratorNode>(menu, position, "Decorators");
menu.ShowAsContext();
}

private void AddItems<T>(DropdownMenu menu, Vector2 position, string menuCategory) where T : class
{
var types = TypeCache.GetTypesDerivedFrom<T>();
foreach (var type in types)
{
if (type.IsAbstract) continue;

var categoryPathAttribute = type.GetCustomAttribute<CategoryPathAttribute>();
string pathSubCategory = categoryPathAttribute?.SubCategoryPath ?? string.Empty;

var isUtilityDesignerAssembly = type.Assembly.GetName().Name == "UtilityDesigner";
var path = isUtilityDesignerAssembly
? $"{menuCategory}/{Utils.AddSpacesBeforeUppercase(type.Name)}"
: $"{menuCategory} (custom)/{Utils.AddSpacesBeforeUppercase(type.Name)}";
: $"{menuCategory} (custom)/{pathSubCategory}/{Utils.AddSpacesBeforeUppercase(type.Name)}".Replace("//", "/");

menu.AppendAction(path, (a) => CreateNode(type, position));
}
}

private void AddItems<T>(GenericMenu menu, Vector2 position, string menuCategory) where T : class
{
var types = TypeCache.GetTypesDerivedFrom<T>();
foreach (var type in types)
{
if (type.IsAbstract) continue;

var categoryPathAttribute = type.GetCustomAttribute<CategoryPathAttribute>();
string pathSubCategory = categoryPathAttribute?.SubCategoryPath ?? string.Empty;

var isUtilityDesignerAssembly = type.Assembly.GetName().Name == "UtilityDesigner";
var path = isUtilityDesignerAssembly
? $"{menuCategory}/{Utils.AddSpacesBeforeUppercase(type.Name)}"
: $"{menuCategory} (custom)/{Utils.AddSpacesBeforeUppercase(type.Name)}";
: $"{menuCategory} (custom)/{pathSubCategory}/{Utils.AddSpacesBeforeUppercase(type.Name)}".Replace("//", "/");

menu.AddItem(new GUIContent(path), false, () => CreateNode(type, position));
}
}
private void CreateNode(Type type, Vector2 pos)

internal void CreateNode(Type type, Vector2 pos)
{
BaseNode node = _behaviourTree.CreateNode(type, pos);
CreateNodeView(node);
Expand Down
Loading