diff --git a/Assets/FluidBehaviorTree/Editor.meta b/Assets/FluidBehaviorTree/Editor.meta new file mode 100644 index 00000000..7c9efa23 --- /dev/null +++ b/Assets/FluidBehaviorTree/Editor.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 9a36ec3d3897e4b7793c45a23ac218c4 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/FluidBehaviorTree/Editor/BehaviorTree.meta b/Assets/FluidBehaviorTree/Editor/BehaviorTree.meta new file mode 100644 index 00000000..5ff084f9 --- /dev/null +++ b/Assets/FluidBehaviorTree/Editor/BehaviorTree.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: d703dfd587c54429f9ad1da1bf6e9507 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/FluidBehaviorTree/Editor/BehaviorTree/BehaviorTreeDrawer.cs b/Assets/FluidBehaviorTree/Editor/BehaviorTree/BehaviorTreeDrawer.cs new file mode 100644 index 00000000..2cd5e142 --- /dev/null +++ b/Assets/FluidBehaviorTree/Editor/BehaviorTree/BehaviorTreeDrawer.cs @@ -0,0 +1,21 @@ +using UnityEditor; +using UnityEngine; + +namespace CleverCrow.Fluid.BTs.Trees.Editors { + [CustomPropertyDrawer(typeof(BehaviorTree))] + public class BehaviorTreeDrawer : PropertyDrawer { + public override void OnGUI (Rect position, SerializedProperty property, GUIContent label) { + EditorGUI.BeginProperty(position, label, property); + + position = EditorGUI.PrefixLabel(position, GUIUtility.GetControlID(FocusType.Passive), label); + GUI.enabled = Application.isPlaying; + if (GUI.Button(position, "View Tree")) { + var tree = fieldInfo.GetValue(property.serializedObject.targetObject) as IBehaviorTree; + BehaviorTreeWindow.ShowTree(tree, tree.Name ?? property.displayName); + } + GUI.enabled = true; + + EditorGUI.EndProperty(); + } + } +} diff --git a/Assets/FluidBehaviorTree/Editor/BehaviorTree/BehaviorTreeDrawer.cs.meta b/Assets/FluidBehaviorTree/Editor/BehaviorTree/BehaviorTreeDrawer.cs.meta new file mode 100644 index 00000000..4124a741 --- /dev/null +++ b/Assets/FluidBehaviorTree/Editor/BehaviorTree/BehaviorTreeDrawer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 524bc0f9047cc46e7b0b7c3143d51ff6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/FluidBehaviorTree/Editor/BehaviorTree/BehaviorTreeWindow.cs b/Assets/FluidBehaviorTree/Editor/BehaviorTree/BehaviorTreeWindow.cs new file mode 100644 index 00000000..08139c43 --- /dev/null +++ b/Assets/FluidBehaviorTree/Editor/BehaviorTree/BehaviorTreeWindow.cs @@ -0,0 +1,41 @@ +using UnityEditor; +using UnityEngine; + +namespace CleverCrow.Fluid.BTs.Trees.Editors { + public class BehaviorTreeWindow : EditorWindow { + private BehaviorTreePrinter _printer; + private string _name; + + public static void ShowTree (IBehaviorTree tree, string name) { + var window = GetWindow(false); + window.titleContent = new GUIContent($"Behavior Tree: {name}"); + window.SetTree(tree, name); + } + + private void SetTree (IBehaviorTree tree, string name) { + _printer?.Unbind(); + _printer = new BehaviorTreePrinter(tree, position.size); + _name = name; + } + + private void OnGUI () { + if (!Application.isPlaying) { + ClearView(); + } + + GUILayout.Label($"Behavior Tree: {_name}", EditorStyles.boldLabel); + _printer?.Print(position.size); + } + + private void ClearView () { + _name = null; + _printer = null; + } + + private void Update () { + if (Application.isPlaying) { + Repaint(); + } + } + } +} diff --git a/Assets/FluidBehaviorTree/Editor/BehaviorTree/BehaviorTreeWindow.cs.meta b/Assets/FluidBehaviorTree/Editor/BehaviorTree/BehaviorTreeWindow.cs.meta new file mode 100644 index 00000000..0e818c1b --- /dev/null +++ b/Assets/FluidBehaviorTree/Editor/BehaviorTree/BehaviorTreeWindow.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: d1e3121e089049fbb2d517264839c8ee +timeCreated: 1559593491 \ No newline at end of file diff --git a/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer.meta b/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer.meta new file mode 100644 index 00000000..90830b8e --- /dev/null +++ b/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 739590391a384b87aeff999f10d39ea9 +timeCreated: 1559595588 \ No newline at end of file diff --git a/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/BehaviorTreePrinter.cs b/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/BehaviorTreePrinter.cs new file mode 100644 index 00000000..39e528d7 --- /dev/null +++ b/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/BehaviorTreePrinter.cs @@ -0,0 +1,51 @@ +using UnityEngine; + +namespace CleverCrow.Fluid.BTs.Trees.Editors { + public class BehaviorTreePrinter { + private const float SCROLL_PADDING = 40; + + private readonly VisualTask _root; + private readonly Rect _containerSize; + + private Vector2 _scrollPosition; + + public static StatusIcons StatusIcons { get; private set; } + public static GuiStyleCollection SharedStyles { get; private set; } + + + public BehaviorTreePrinter (IBehaviorTree tree, Vector2 windowSize) { + StatusIcons = new StatusIcons(); + SharedStyles = new GuiStyleCollection(); + + var container = new GraphContainerVertical(); + container.SetGlobalPosition(SCROLL_PADDING, SCROLL_PADDING); + _root = new VisualTask(tree.Root, container); + container.CenterAlignChildren(); + + _containerSize = new Rect(0, 0, + container.Width + SCROLL_PADDING * 2, + container.Height + SCROLL_PADDING * 2); + + CenterScrollView(windowSize, container); + } + + private void CenterScrollView (Vector2 windowSize, GraphContainerVertical container) { + var scrollOverflow = container.Width + SCROLL_PADDING * 2 - windowSize.x; + var centerViewPosition = scrollOverflow / 2; + _scrollPosition.x = centerViewPosition; + } + + public void Print (Vector2 windowSize) { + _scrollPosition = GUI.BeginScrollView( + new Rect(0, 0, windowSize.x, windowSize.y), + _scrollPosition, + _containerSize); + _root.Print(); + GUI.EndScrollView(); + } + + public void Unbind () { + _root.RecursiveTaskUnbind(); + } + } +} \ No newline at end of file diff --git a/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/BehaviorTreePrinter.cs.meta b/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/BehaviorTreePrinter.cs.meta new file mode 100644 index 00000000..15231305 --- /dev/null +++ b/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/BehaviorTreePrinter.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 6158970d66744d0fad57971df425241a +timeCreated: 1559594429 \ No newline at end of file diff --git a/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/Containers.meta b/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/Containers.meta new file mode 100644 index 00000000..76d00af0 --- /dev/null +++ b/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/Containers.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 7fbdf5642077480492b0bc99e6349cde +timeCreated: 1559834379 \ No newline at end of file diff --git a/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/Containers/GraphBox.cs b/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/Containers/GraphBox.cs new file mode 100644 index 00000000..510ccd02 --- /dev/null +++ b/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/Containers/GraphBox.cs @@ -0,0 +1,46 @@ +using System.Collections.Generic; + +namespace CleverCrow.Fluid.BTs.Trees.Editors { + public class GraphBox : IGraphBox { + public List ChildContainers { get; } = new List(); + public bool SkipCentering { get; set; } + + public float LocalPositionX { get; private set; } + public float LocalPositionY { get; private set; } + + public float GlobalPositionX { get; private set; } + public float GlobalPositionY { get; private set; } + + public float Width { get; private set; } + public float Height { get; private set; } + + public float PaddingX { get; private set; } + public float PaddingY { get; private set; } + + public void SetSize (float width, float height) { + Width = width; + Height = height; + } + + public void SetPadding (float x, float y) { + Width += x; + Height += y; + + PaddingX = x; + PaddingY = y; + } + + public void CenterAlignChildren () { + } + + public void SetLocalPosition (float x, float y) { + LocalPositionX = x; + LocalPositionY = y; + } + + public void AddGlobalPosition (float x, float y) { + GlobalPositionX += x; + GlobalPositionY += y; + } + } +} \ No newline at end of file diff --git a/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/Containers/GraphBox.cs.meta b/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/Containers/GraphBox.cs.meta new file mode 100644 index 00000000..5142a716 --- /dev/null +++ b/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/Containers/GraphBox.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4b7923b9df39dde43b0410a63fd592c9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/Containers/GraphContainerHorizontal.cs b/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/Containers/GraphContainerHorizontal.cs new file mode 100644 index 00000000..a75494db --- /dev/null +++ b/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/Containers/GraphContainerHorizontal.cs @@ -0,0 +1,70 @@ +using System.Collections.Generic; + +namespace CleverCrow.Fluid.BTs.Trees.Editors { + public class GraphContainerHorizontal : IGraphContainer { + protected readonly List _childContainers = new List(); + + public float LocalPositionX { get; private set; } + public float LocalPositionY { get; private set; } + public float GlobalPositionX { get; private set; } + public float GlobalPositionY { get; private set; } + public float Width { get; protected set; } + public float Height { get; protected set; } + public float PaddingX { get; } + public float PaddingY { get; } + public List ChildContainers => _childContainers; + + public void SetLocalPosition (float x, float y) { + LocalPositionX = x; + LocalPositionY = y; + } + + public virtual void AddBox (IGraphBox child) { + CalculateChild(child); + _childContainers.Add(child); + } + + private void CalculateChild (IGraphBox child) { + child.SetLocalPosition(Width, 0); + child.AddGlobalPosition(GlobalPositionX + child.LocalPositionX, GlobalPositionY + child.LocalPositionY); + + Width += child.Width; + if (child.Height > Height) Height = child.Height; + } + + public void SetSize (float width, float height) { + throw new System.NotImplementedException(); + } + + public void SetGlobalPosition (float x, float y) { + GlobalPositionX = x; + GlobalPositionY = y; + } + + public void AddGlobalPosition (float x, float y) { + GlobalPositionX += x; + GlobalPositionY += y; + + foreach (var child in ChildContainers) { + child.AddGlobalPosition(x, y); + } + } + + public void SetPadding (float x, float y) { + throw new System.NotImplementedException(); + } + + public override string ToString () { + return + $"Size: {Width}, {Height}; Local: {LocalPositionX}, {LocalPositionY}; Global: {GlobalPositionX}, {GlobalPositionY};"; + } + + public virtual void CenterAlignChildren () { + foreach (var child in _childContainers) { + child.CenterAlignChildren(); + } + } + + public bool SkipCentering { get; } + } +} \ No newline at end of file diff --git a/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/Containers/GraphContainerHorizontal.cs.meta b/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/Containers/GraphContainerHorizontal.cs.meta new file mode 100644 index 00000000..ebba1708 --- /dev/null +++ b/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/Containers/GraphContainerHorizontal.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 7e3d59e40e214d1c9bdf66de4dcdb528 +timeCreated: 1559834631 \ No newline at end of file diff --git a/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/Containers/GraphContainerVertical.cs b/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/Containers/GraphContainerVertical.cs new file mode 100644 index 00000000..dd3bc265 --- /dev/null +++ b/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/Containers/GraphContainerVertical.cs @@ -0,0 +1,41 @@ +using System.Collections.Generic; + +namespace CleverCrow.Fluid.BTs.Trees.Editors { + public class GraphContainerVertical : GraphContainerHorizontal { + public override void AddBox (IGraphBox child) { + CalculateChild(child); + _childContainers.Add(child); + } + + private void CalculateChild (IGraphBox child) { + child.SetLocalPosition(0, Height); + child.AddGlobalPosition(GlobalPositionX + child.LocalPositionX, GlobalPositionY + child.LocalPositionY); + + Height += child.Height; + if (child.Width > Width) Width = child.Width; + } + + public override void CenterAlignChildren () { + var positions = GetCenterAlignLocalPositions(); + + for (var i = 0; i < _childContainers.Count; i++) { + var child = _childContainers[i]; + if (child.SkipCentering) continue; + child.AddGlobalPosition(positions[i], 0); + child.CenterAlignChildren(); + } + } + + private List GetCenterAlignLocalPositions () { + var list = new List(); + foreach (var child in _childContainers) { + var gap = Width - child.Width; + var shift = gap / 2f; + + list.Add(shift); + } + + return list; + } + } +} \ No newline at end of file diff --git a/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/Containers/GraphContainerVertical.cs.meta b/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/Containers/GraphContainerVertical.cs.meta new file mode 100644 index 00000000..c7da0bfa --- /dev/null +++ b/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/Containers/GraphContainerVertical.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 41c2bd31f8684f4790055b52bfb8fe3a +timeCreated: 1559834670 \ No newline at end of file diff --git a/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/Containers/IGraphBox.cs b/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/Containers/IGraphBox.cs new file mode 100644 index 00000000..2659fff2 --- /dev/null +++ b/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/Containers/IGraphBox.cs @@ -0,0 +1,25 @@ +using System.Collections.Generic; + +namespace CleverCrow.Fluid.BTs.Trees.Editors { + public interface IGraphBox { + List ChildContainers { get; } + + float LocalPositionX { get; } + float LocalPositionY { get; } + float GlobalPositionX { get; } + float GlobalPositionY { get; } + + float Width { get; } + float Height { get; } + float PaddingX { get; } + float PaddingY { get; } + + void SetSize (float width, float height); + void SetLocalPosition (float x, float y); + void AddGlobalPosition (float x, float y); + void SetPadding (float x, float y); + void CenterAlignChildren (); + + bool SkipCentering { get; } + } +} \ No newline at end of file diff --git a/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/Containers/IGraphBox.cs.meta b/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/Containers/IGraphBox.cs.meta new file mode 100644 index 00000000..bd624ff2 --- /dev/null +++ b/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/Containers/IGraphBox.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 6a44321bd59241998d893d4570d363fc +timeCreated: 1559834575 \ No newline at end of file diff --git a/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/Containers/IGraphContainer.cs b/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/Containers/IGraphContainer.cs new file mode 100644 index 00000000..7d9ec78e --- /dev/null +++ b/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/Containers/IGraphContainer.cs @@ -0,0 +1,5 @@ +namespace CleverCrow.Fluid.BTs.Trees.Editors { + public interface IGraphContainer : IGraphBox { + void AddBox (IGraphBox container); + } +} \ No newline at end of file diff --git a/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/Containers/IGraphContainer.cs.meta b/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/Containers/IGraphContainer.cs.meta new file mode 100644 index 00000000..6fbb17d6 --- /dev/null +++ b/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/Containers/IGraphContainer.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 5e7f5febdcd04eacb19bff91c74a1b43 +timeCreated: 1559834598 \ No newline at end of file diff --git a/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/GraphNode.meta b/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/GraphNode.meta new file mode 100644 index 00000000..90dde181 --- /dev/null +++ b/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/GraphNode.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 37e7066e1c1544cdacaa4ecbd9a8f6f4 +timeCreated: 1559784711 \ No newline at end of file diff --git a/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/GraphNode/GraphNode.cs b/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/GraphNode/GraphNode.cs new file mode 100644 index 00000000..b5112664 --- /dev/null +++ b/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/GraphNode/GraphNode.cs @@ -0,0 +1,62 @@ +using System.Collections.Generic; +using CleverCrow.Fluid.BTs.Tasks; +using UnityEngine; + +namespace CleverCrow.Fluid.BTs.Trees.Editors { + public class GraphNode { + private IGraphNodePrinter _printer; + + public float ContainerHeight => Size.y + + VerticalConnectorBottomHeight + + HorizontalConnectorHeight + + VerticalConnectorTopHeight; + + public Vector2 Position { get; private set; } + public List Children { get; } = new List(); + public Vector2 Size { get; } + public ITask Task { get; } + public int VerticalConnectorBottomHeight { get; } + public int VerticalConnectorTopHeight { get; } + public int HorizontalConnectorHeight { get; } + + public GraphNode (ITask task, IGraphNodePrinter printer, GraphNodeOptions options) { + _printer = printer; + Task = task; + + Size = options.Size; + VerticalConnectorBottomHeight = options.VerticalConnectorBottomHeight; + VerticalConnectorTopHeight = options.VerticalConnectorTopHeight; + HorizontalConnectorHeight = options.HorizontalConnectorHeight; + + if (task.Children == null) return; + foreach (var child in task.Children) { + Children.Add(new GraphNode(child, printer, options)); + } + } + + public void SetPosition (Vector2 position) { + Position = position; + + for (var i = 0; i < Children.Count; i++) { + var child = Children[i]; + var childPos = new Vector2(position.x, position.y + ContainerHeight); + + // Center the child, then align it to the expected position + childPos.x += Size.x / 2 + Size.x * i; + + // Shift the child as if it were in a container so it lines up properly + childPos.x -= Size.x * (Children.Count / 2f); + + child.SetPosition(childPos); + } + } + + public void Print () { + _printer.Print(this); + + foreach (var child in Children) { + child.Print(); + } + } + } +} diff --git a/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/GraphNode/GraphNode.cs.meta b/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/GraphNode/GraphNode.cs.meta new file mode 100644 index 00000000..ba0d3a13 --- /dev/null +++ b/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/GraphNode/GraphNode.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: ac61471e395b4d409ba3a9e909ae1baa +timeCreated: 1559689769 \ No newline at end of file diff --git a/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/GraphNode/GraphNodeOptions.cs b/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/GraphNode/GraphNodeOptions.cs new file mode 100644 index 00000000..07992d84 --- /dev/null +++ b/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/GraphNode/GraphNodeOptions.cs @@ -0,0 +1,10 @@ +using UnityEngine; + +namespace CleverCrow.Fluid.BTs.Trees.Editors { + public class GraphNodeOptions { + public int VerticalConnectorBottomHeight { get; set; } + public int HorizontalConnectorHeight { get; set; } + public int VerticalConnectorTopHeight { get; set; } + public Vector2 Size { get; set; } = new Vector2(50, 100); + } +} \ No newline at end of file diff --git a/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/GraphNode/GraphNodeOptions.cs.meta b/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/GraphNode/GraphNodeOptions.cs.meta new file mode 100644 index 00000000..90d2c372 --- /dev/null +++ b/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/GraphNode/GraphNodeOptions.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: fa6c096b702e40678482c0f8b9da9fac +timeCreated: 1559755452 \ No newline at end of file diff --git a/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/GraphNode/GraphNodePrinter.cs b/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/GraphNode/GraphNodePrinter.cs new file mode 100644 index 00000000..8e11bde8 --- /dev/null +++ b/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/GraphNode/GraphNodePrinter.cs @@ -0,0 +1,49 @@ +using System.Linq; +using CleverCrow.Fluid.BTs.TaskParents; +using UnityEngine; + +namespace CleverCrow.Fluid.BTs.Trees.Editors { + public interface IGraphNodePrinter { + void Print (GraphNode node); + } + + public class GraphNodePrinter : IGraphNodePrinter { + private Texture2D _verticalBottom; + private Texture2D _verticalTop; + + public void Print (GraphNode node) { + var rect = new Rect(node.Position, node.Size); + GUI.Box(rect, node.Task.Name); + + PaintVerticalBottom(node, rect); + + if (!(node.Task is TaskRoot)) { + PaintVerticalTop(node, rect); + } + } + + private void PaintVerticalBottom (GraphNode node, Rect nodeRect) { + if (_verticalBottom == null) _verticalBottom = CreateTexture(1, node.VerticalConnectorBottomHeight, Color.black); + var verticalBottomRect = new Rect(nodeRect); + verticalBottomRect.x += node.Size.x / 2 - 0.5f; + verticalBottomRect.y += node.Size.y; + GUI.Label(verticalBottomRect, _verticalBottom); + } + + private void PaintVerticalTop (GraphNode node, Rect nodeRect) { + if (_verticalTop == null) _verticalTop = CreateTexture(1, node.VerticalConnectorTopHeight, Color.black); + var verticalTopRect = new Rect(nodeRect); + verticalTopRect.x += node.Size.x / 2 - 0.5f; + verticalTopRect.y -= node.VerticalConnectorTopHeight; + GUI.Label(verticalTopRect, _verticalTop); + } + + private Texture2D CreateTexture (int width, int height, Color color) { + var texture = new Texture2D(width, height, TextureFormat.ARGB32, false); + texture.SetPixels(Enumerable.Repeat(color, width * height).ToArray()); + texture.Apply(); + + return texture; + } + } +} diff --git a/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/GraphNode/GraphNodePrinter.cs.meta b/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/GraphNode/GraphNodePrinter.cs.meta new file mode 100644 index 00000000..b6783316 --- /dev/null +++ b/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/GraphNode/GraphNodePrinter.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 7ac063fc2c4c4ef9a5a67b5fd06ba3ec +timeCreated: 1559696764 \ No newline at end of file diff --git a/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/Graphics.meta b/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/Graphics.meta new file mode 100644 index 00000000..c580d775 --- /dev/null +++ b/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/Graphics.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: d58293309c274363b7e9fc5afbbdd785 +timeCreated: 1560026210 \ No newline at end of file diff --git a/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/Graphics/AssetPath.cs b/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/Graphics/AssetPath.cs new file mode 100644 index 00000000..fb428f0e --- /dev/null +++ b/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/Graphics/AssetPath.cs @@ -0,0 +1,34 @@ +using UnityEditor; +using UnityEngine; + +namespace CleverCrow.Fluid.BTs.Trees.Editors { + /// + /// Determine if this is a package of the Unity Editor since Unity has no API to determine this + /// + public static class AssetPath { + private const string PATH_PROJECT = "Assets/FluidBehaviorTree"; + private const string PATH_PACKAGE = "Packages/com.fluid.behavior-tree"; + + private static string _basePath; + + public static string BasePath { + get { + if (_basePath != null) return _basePath; + + if (AssetDatabase.IsValidFolder(PATH_PACKAGE)) { + _basePath = PATH_PACKAGE; + return _basePath; + } + + if (AssetDatabase.IsValidFolder(PATH_PROJECT)) { + _basePath = PATH_PROJECT; + return _basePath; + } + + Debug.LogError("Asset root could not be found"); + + return null; + } + } + } +} \ No newline at end of file diff --git a/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/Graphics/AssetPath.cs.meta b/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/Graphics/AssetPath.cs.meta new file mode 100644 index 00000000..0331d460 --- /dev/null +++ b/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/Graphics/AssetPath.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 29b5a281bd9448278c9a641d4af7c56b +timeCreated: 1560039484 \ No newline at end of file diff --git a/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/Graphics/ColorFader.cs b/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/Graphics/ColorFader.cs new file mode 100644 index 00000000..8ead1a53 --- /dev/null +++ b/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/Graphics/ColorFader.cs @@ -0,0 +1,32 @@ +using UnityEngine; + +namespace CleverCrow.Fluid.BTs.Trees.Editors { + public class ColorFader { + const float FADE_DURATION = 0.5f; + + private float _fadeTime; + private readonly Color _startColor; + private readonly Color _endColor; + + public Color CurrentColor { get; private set; } + + public ColorFader (Color start, Color endColor) { + _startColor = start; + _endColor = endColor; + } + + public void Update (bool reset) { + if (reset) { + _fadeTime = FADE_DURATION; + } else { + _fadeTime -= Time.deltaTime; + _fadeTime = Mathf.Max(_fadeTime, 0); + } + + CurrentColor = Color.Lerp( + _startColor, + _endColor, + _fadeTime / FADE_DURATION); + } + } +} diff --git a/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/Graphics/ColorFader.cs.meta b/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/Graphics/ColorFader.cs.meta new file mode 100644 index 00000000..f5565f81 --- /dev/null +++ b/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/Graphics/ColorFader.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 24dd00a48b744508b8968d6b4ac89dfb +timeCreated: 1559959537 \ No newline at end of file diff --git a/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/Graphics/NodeBoxStyle.cs b/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/Graphics/NodeBoxStyle.cs new file mode 100644 index 00000000..25bd4040 --- /dev/null +++ b/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/Graphics/NodeBoxStyle.cs @@ -0,0 +1,30 @@ +using System.Linq; +using UnityEngine; + +namespace CleverCrow.Fluid.BTs.Trees.Editors { + public class NodeBoxStyle { + public GUIStyle Style { get; } + + public NodeBoxStyle (Color32 border, Color background) { + var texture = CreateTexture(19, 19, border); + texture.SetPixels(1, 1, 17, 17, + Enumerable.Repeat(background, 17 * 17).ToArray()); + texture.Apply(); + + Style = new GUIStyle(GUI.skin.box) { + border = new RectOffset(1, 1, 1, 1), + normal = { + background = texture, + }, + }; + } + + private static Texture2D CreateTexture (int width, int height, Color color) { + var texture = new Texture2D(width, height, TextureFormat.ARGB32, false); + texture.SetPixels(Enumerable.Repeat(color, width * height).ToArray()); + texture.Apply(); + + return texture; + } + } +} \ No newline at end of file diff --git a/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/Graphics/NodeBoxStyle.cs.meta b/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/Graphics/NodeBoxStyle.cs.meta new file mode 100644 index 00000000..be4580d9 --- /dev/null +++ b/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/Graphics/NodeBoxStyle.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: fb7e76da847c4756b7091dde1962020d +timeCreated: 1560027484 \ No newline at end of file diff --git a/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/Graphics/NodeBoxStyleCollection.cs b/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/Graphics/NodeBoxStyleCollection.cs new file mode 100644 index 00000000..d509fb21 --- /dev/null +++ b/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/Graphics/NodeBoxStyleCollection.cs @@ -0,0 +1,18 @@ +using UnityEngine; + +namespace CleverCrow.Fluid.BTs.Trees.Editors { + public class GuiStyleCollection { + public NodeBoxStyle BoxActive { get; } = new NodeBoxStyle(Color.gray, Color.white); + + public NodeBoxStyle BoxInactive { get; } = new NodeBoxStyle( + new Color32(150, 150, 150, 255), + new Color32(208, 208, 208, 255)); + + public GUIStyle Title { get; } = new GUIStyle(GUI.skin.label) { + fontSize = 9, + alignment = TextAnchor.LowerCenter, + wordWrap = true, + padding = new RectOffset(3, 3, 3, 3), + }; + } +} diff --git a/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/Graphics/NodeBoxStyleCollection.cs.meta b/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/Graphics/NodeBoxStyleCollection.cs.meta new file mode 100644 index 00000000..4dcfbac8 --- /dev/null +++ b/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/Graphics/NodeBoxStyleCollection.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: b010848be7db435a93eb237039e42d04 +timeCreated: 1560026196 \ No newline at end of file diff --git a/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/Graphics/NodeFaders.cs b/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/Graphics/NodeFaders.cs new file mode 100644 index 00000000..0514ffc6 --- /dev/null +++ b/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/Graphics/NodeFaders.cs @@ -0,0 +1,20 @@ +using UnityEngine; + +namespace CleverCrow.Fluid.BTs.Trees.Editors { + public class NodeFaders { + public ColorFader BackgroundFader { get; } = new ColorFader( + new Color(0.65f, 0.65f, 0.65f), new Color(0.39f, 0.78f, 0.39f)); + + public ColorFader TextFader { get; } = new ColorFader( + Color.white, Color.black); + + public ColorFader MainIconFader { get; } = new ColorFader( + new Color(1, 1, 1, 0.3f), new Color(1, 1, 1, 1f)); + + public void Update (bool active) { + BackgroundFader.Update(active); + TextFader.Update(active); + MainIconFader.Update(active); + } + } +} \ No newline at end of file diff --git a/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/Graphics/NodeFaders.cs.meta b/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/Graphics/NodeFaders.cs.meta new file mode 100644 index 00000000..0b87eb8b --- /dev/null +++ b/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/Graphics/NodeFaders.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: f3ea63308c9a4f51811db1689a330fff +timeCreated: 1560031876 \ No newline at end of file diff --git a/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/Graphics/StatusIcons.cs b/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/Graphics/StatusIcons.cs new file mode 100644 index 00000000..d7230e5d --- /dev/null +++ b/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/Graphics/StatusIcons.cs @@ -0,0 +1,25 @@ +using System; +using CleverCrow.Fluid.BTs.Tasks; + +namespace CleverCrow.Fluid.BTs.Trees.Editors { + public class StatusIcons { + private const string ICON_STATUS_PATH = "ROOT/Editor/Icons/Status"; + + private TextureLoader Success { get; } = new TextureLoader($"{ICON_STATUS_PATH}/Success.png"); + private TextureLoader Failure { get; } = new TextureLoader($"{ICON_STATUS_PATH}/Failure.png"); + private TextureLoader Continue { get; } = new TextureLoader($"{ICON_STATUS_PATH}/Continue.png"); + + public TextureLoader GetIcon (TaskStatus status) { + switch (status) { + case TaskStatus.Success: + return Success; + case TaskStatus.Failure: + return Failure; + case TaskStatus.Continue: + return Continue; + default: + throw new ArgumentOutOfRangeException(nameof(status), status, null); + } + } + } +} diff --git a/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/Graphics/StatusIcons.cs.meta b/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/Graphics/StatusIcons.cs.meta new file mode 100644 index 00000000..f9687721 --- /dev/null +++ b/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/Graphics/StatusIcons.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: ceee52c2d5524268ade30a38e559229b +timeCreated: 1560024638 \ No newline at end of file diff --git a/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/Graphics/TextureLoader.cs b/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/Graphics/TextureLoader.cs new file mode 100644 index 00000000..de3124aa --- /dev/null +++ b/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/Graphics/TextureLoader.cs @@ -0,0 +1,23 @@ +using UnityEditor; +using UnityEngine; + +namespace CleverCrow.Fluid.BTs.Trees.Editors { + public class TextureLoader { + public Texture2D Texture { get; } + + public TextureLoader (string spritePath) { + Texture = AssetDatabase.LoadAssetAtPath( + spritePath.Replace("ROOT", AssetPath.BasePath)); + } + + public void Paint (Rect rect, Color color) { + var oldColor = GUI.color; + GUI.color = color; + + if (Texture == null) return; + GUI.Label(rect, Texture); + + GUI.color = oldColor; + } + } +} diff --git a/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/Graphics/TextureLoader.cs.meta b/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/Graphics/TextureLoader.cs.meta new file mode 100644 index 00000000..dd243786 --- /dev/null +++ b/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/Graphics/TextureLoader.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 7765957e60ab4444ab2aa1a6fc6322b2 +timeCreated: 1560023700 \ No newline at end of file diff --git a/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/NodePrintController.cs b/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/NodePrintController.cs new file mode 100644 index 00000000..9d3a7031 --- /dev/null +++ b/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/NodePrintController.cs @@ -0,0 +1,144 @@ +using System.Linq; +using CleverCrow.Fluid.BTs.TaskParents; +using UnityEngine; + +namespace CleverCrow.Fluid.BTs.Trees.Editors { + public class NodePrintController { + private readonly VisualTask _node; + private readonly IGraphBox _box; + private readonly IGraphBox _divider; + private readonly NodeFaders _faders = new NodeFaders(); + + private readonly TextureLoader _iconMain; + + private Texture2D _dividerGraphic; + private Texture2D _verticalBottom; + private Texture2D _verticalTop; + + private static GuiStyleCollection Styles => BehaviorTreePrinter.SharedStyles; + + public NodePrintController (VisualTask node) { + _node = node; + _box = node.Box; + _divider = node.Divider; + _iconMain = new TextureLoader(_node.Task.IconPath); + } + + public void Print (bool taskIsActive) { + if (!(_node.Task is TaskRoot)) PaintVerticalTop(); + _faders.Update(taskIsActive); + + PaintBody(); + + if (_node.Children.Count > 0) { + PaintDivider(); + PaintVerticalBottom(); + } + } + + private void PaintBody () { + var prevBackgroundColor = GUI.backgroundColor; + + var rect = new Rect( + _box.GlobalPositionX + _box.PaddingX, + _box.GlobalPositionY + _box.PaddingY, + _box.Width - _box.PaddingX, + _box.Height - _box.PaddingY); + + if (_node.Task.HasBeenActive) { + GUI.backgroundColor = _faders.BackgroundFader.CurrentColor; + GUI.Box(rect, GUIContent.none, Styles.BoxActive.Style); + GUI.backgroundColor = prevBackgroundColor; + + PrintLastStatus(rect); + } else { + GUI.Box(rect, GUIContent.none, Styles.BoxInactive.Style); + } + + PrintIcon(); + + Styles.Title.normal.textColor = _faders.TextFader.CurrentColor; + GUI.Label(rect, _node.Task.Name, Styles.Title); + } + + private void PrintLastStatus (Rect rect) { + const float sidePadding = 1.5f; + + var icon = BehaviorTreePrinter.StatusIcons.GetIcon(_node.Task.LastStatus); + icon.Paint( + new Rect( + rect.x + rect.size.x - icon.Texture.width - sidePadding, + rect.y + rect.size.y - icon.Texture.height - sidePadding, + icon.Texture.width, icon.Texture.height), + new Color(1, 1, 1, 0.7f)); + } + + private void PrintIcon () { + const float iconWidth = 35; + const float iconHeight = 35; + _iconMain.Paint( + new Rect( + _box.GlobalPositionX + _box.PaddingX / 2 + _box.Width / 2 - iconWidth / 2 + _node.Task.IconPadding / 2, + _box.GlobalPositionY + _box.PaddingX / 2 + 3 + _node.Task.IconPadding / 2, + iconWidth - _node.Task.IconPadding, + iconHeight - _node.Task.IconPadding), + _faders.MainIconFader.CurrentColor); + } + + private void PaintDivider () { + const int graphicSizeIncrease = 5; + + if (_dividerGraphic == null) { + _dividerGraphic = CreateTexture( + (int)_divider.Width + graphicSizeIncrease, + 1, + Color.black); + } + + var position = new Rect( + _divider.GlobalPositionX + _box.PaddingY / 2 + _node.DividerLeftOffset - 2, + // @TODO Should not need to offset this + _divider.GlobalPositionY + _box.PaddingY / 2, + _divider.Width + graphicSizeIncrease, + 10); + + GUI.Label(position, _dividerGraphic); + } + + private void PaintVerticalBottom () { + if (_verticalBottom == null) { + _verticalBottom = CreateTexture(1, (int)_box.PaddingY, Color.black); + } + + var position = new Rect( + _box.GlobalPositionX + _node.Width / 2 + _box.PaddingX - 2, + _box.GlobalPositionY + _node.Height + _box.PaddingY - 1, + 100, + _box.PaddingY - 1); + + GUI.Label(position, _verticalBottom); + } + + private void PaintVerticalTop () { + if (_verticalTop == null) { + _verticalTop = CreateTexture(1, Mathf.RoundToInt(_box.PaddingY / 2), Color.black); + } + + var position = new Rect( + _box.GlobalPositionX + _node.Width / 2 + _box.PaddingX - 2, + _box.GlobalPositionY + _box.PaddingY / 2, + 100, + 10); + + GUI.Label(position, _verticalTop); + } + + private static Texture2D CreateTexture (int width, int height, Color color) { + var texture = new Texture2D(width, height, TextureFormat.ARGB32, false); + texture.SetPixels(Enumerable.Repeat(color, width * height).ToArray()); + texture.Apply(); + + return texture; + } + } +} diff --git a/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/NodePrintController.cs.meta b/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/NodePrintController.cs.meta new file mode 100644 index 00000000..f290b932 --- /dev/null +++ b/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/NodePrintController.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 682ad99c096c4036a73f51eadcda7ea3 +timeCreated: 1559940435 \ No newline at end of file diff --git a/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/VisualTask.cs b/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/VisualTask.cs new file mode 100644 index 00000000..f0f46e26 --- /dev/null +++ b/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/VisualTask.cs @@ -0,0 +1,89 @@ +using System.Collections.Generic; +using CleverCrow.Fluid.BTs.Tasks; + +namespace CleverCrow.Fluid.BTs.Trees.Editors { + public class VisualTask { + private readonly List _children = new List(); + private readonly NodePrintController _printer; + private bool _taskActive; + + public ITask Task { get; } + public IReadOnlyList Children => _children; + + public float Width { get; } = 70; + public float Height { get; } = 50; + + public IGraphBox Box { get; private set; } + public IGraphBox Divider { get; private set; } + public float DividerLeftOffset { get; private set; } + + public VisualTask (ITask task, IGraphContainer parentContainer) { + Task = task; + BindTask(); + + var container = new GraphContainerVertical(); + + AddBox(container); + + if (task.Children != null) { + var childContainer = new GraphContainerHorizontal(); + foreach (var child in task.Children) { + _children.Add(new VisualTask(child, childContainer)); + } + + AddDivider(container, childContainer); + container.AddBox(childContainer); + } + + parentContainer.AddBox(container); + + _printer = new NodePrintController(this); + } + + private void BindTask () { + Task.EditorUtils.EventActive.AddListener(UpdateTaskActiveStatus); + } + + public void RecursiveTaskUnbind () { + Task.EditorUtils.EventActive.RemoveListener(UpdateTaskActiveStatus); + + foreach (var child in _children) { + child.RecursiveTaskUnbind(); + } + } + + private void UpdateTaskActiveStatus () { + _taskActive = true; + } + + private void AddDivider (IGraphContainer parent, IGraphContainer children) { + Divider = new GraphBox { + SkipCentering = true, + }; + + DividerLeftOffset = children.ChildContainers[0].Width / 2; + var dividerRightOffset = children.ChildContainers[children.ChildContainers.Count - 1].Width / 2; + var width = children.Width - DividerLeftOffset - dividerRightOffset; + + Divider.SetSize(width, 1); + + parent.AddBox(Divider); + } + + private void AddBox (IGraphContainer parent) { + Box = new GraphBox(); + Box.SetSize(Width, Height); + Box.SetPadding(10, 10); + parent.AddBox(Box); + } + + public void Print () { + _printer.Print(_taskActive); + _taskActive = false; + + foreach (var child in _children) { + child.Print(); + } + } + } +} diff --git a/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/VisualTask.cs.meta b/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/VisualTask.cs.meta new file mode 100644 index 00000000..80cedeba --- /dev/null +++ b/Assets/FluidBehaviorTree/Editor/BehaviorTree/Printer/VisualTask.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: b9ba57518b7f4e1883c6f635117ea504 +timeCreated: 1559784748 \ No newline at end of file diff --git a/Assets/FluidBehaviorTree/Editor/Fluid.BehaviorTree.Editor.asmdef b/Assets/FluidBehaviorTree/Editor/Fluid.BehaviorTree.Editor.asmdef new file mode 100644 index 00000000..35da73e9 --- /dev/null +++ b/Assets/FluidBehaviorTree/Editor/Fluid.BehaviorTree.Editor.asmdef @@ -0,0 +1,12 @@ +{ + "name": "Fluid.BehaviorTree.Editor", + "references": [ + "Fluid.BehaviorTree" + ], + "optionalUnityReferences": [], + "includePlatforms": [ + "Editor" + ], + "excludePlatforms": [], + "allowUnsafeCode": false +} diff --git a/Assets/FluidBehaviorTree/Editor/Fluid.BehaviorTree.Editor.asmdef.meta b/Assets/FluidBehaviorTree/Editor/Fluid.BehaviorTree.Editor.asmdef.meta new file mode 100644 index 00000000..b3ac7be2 --- /dev/null +++ b/Assets/FluidBehaviorTree/Editor/Fluid.BehaviorTree.Editor.asmdef.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 513d36fa6183b4515a2308f14edcd5dc +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/FluidBehaviorTree/Editor/Icons.meta b/Assets/FluidBehaviorTree/Editor/Icons.meta new file mode 100644 index 00000000..49a3fd11 --- /dev/null +++ b/Assets/FluidBehaviorTree/Editor/Icons.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: cd481df6dae560643840c7b6d05d887d +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/FluidBehaviorTree/Editor/Icons/Status.meta b/Assets/FluidBehaviorTree/Editor/Icons/Status.meta new file mode 100644 index 00000000..bc02c4a7 --- /dev/null +++ b/Assets/FluidBehaviorTree/Editor/Icons/Status.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: da017f0fd976a3242991e9a16136e474 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/FluidBehaviorTree/Editor/Icons/Status/Continue.png b/Assets/FluidBehaviorTree/Editor/Icons/Status/Continue.png new file mode 100644 index 00000000..4752baba Binary files /dev/null and b/Assets/FluidBehaviorTree/Editor/Icons/Status/Continue.png differ diff --git a/Assets/FluidBehaviorTree/Editor/Icons/Status/Continue.png.meta b/Assets/FluidBehaviorTree/Editor/Icons/Status/Continue.png.meta new file mode 100644 index 00000000..170fe110 --- /dev/null +++ b/Assets/FluidBehaviorTree/Editor/Icons/Status/Continue.png.meta @@ -0,0 +1,101 @@ +fileFormatVersion: 2 +guid: a41f32dc3a3e363489402655782db981 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 10 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: 1 + mipBias: -100 + wrapU: 1 + wrapV: 1 + wrapW: -1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 1 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - serializedVersion: 2 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - serializedVersion: 2 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: 49a83db643d6c614b8c222f87d73b30c + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/FluidBehaviorTree/Editor/Icons/Status/Failure.png b/Assets/FluidBehaviorTree/Editor/Icons/Status/Failure.png new file mode 100644 index 00000000..67f24c33 Binary files /dev/null and b/Assets/FluidBehaviorTree/Editor/Icons/Status/Failure.png differ diff --git a/Assets/FluidBehaviorTree/Editor/Icons/Status/Failure.png.meta b/Assets/FluidBehaviorTree/Editor/Icons/Status/Failure.png.meta new file mode 100644 index 00000000..e0c86b54 --- /dev/null +++ b/Assets/FluidBehaviorTree/Editor/Icons/Status/Failure.png.meta @@ -0,0 +1,101 @@ +fileFormatVersion: 2 +guid: b592946378a1d8b44a5673139f68dd7d +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 10 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: 1 + mipBias: -100 + wrapU: 1 + wrapV: 1 + wrapW: -1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 1 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - serializedVersion: 2 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - serializedVersion: 2 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: 022b588ee67de8645a6c4153b6c8509e + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/FluidBehaviorTree/Editor/Icons/Status/Success.png b/Assets/FluidBehaviorTree/Editor/Icons/Status/Success.png new file mode 100644 index 00000000..996ca24f Binary files /dev/null and b/Assets/FluidBehaviorTree/Editor/Icons/Status/Success.png differ diff --git a/Assets/FluidBehaviorTree/Editor/Icons/Status/Success.png.meta b/Assets/FluidBehaviorTree/Editor/Icons/Status/Success.png.meta new file mode 100644 index 00000000..0155b5da --- /dev/null +++ b/Assets/FluidBehaviorTree/Editor/Icons/Status/Success.png.meta @@ -0,0 +1,101 @@ +fileFormatVersion: 2 +guid: 5bfe28789dd636b45977ff7b559489d8 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 10 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: 1 + mipBias: -100 + wrapU: 1 + wrapV: 1 + wrapW: -1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 1 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - serializedVersion: 2 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - serializedVersion: 2 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: 6c97db65552371c4bb75656c56bc2104 + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/FluidBehaviorTree/Editor/Icons/Tasks.meta b/Assets/FluidBehaviorTree/Editor/Icons/Tasks.meta new file mode 100644 index 00000000..3cd10b21 --- /dev/null +++ b/Assets/FluidBehaviorTree/Editor/Icons/Tasks.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 3a90873ec7f20e74987761b278f428b2 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/FluidBehaviorTree/Editor/Icons/Tasks/Cancel.png b/Assets/FluidBehaviorTree/Editor/Icons/Tasks/Cancel.png new file mode 100644 index 00000000..573e2041 Binary files /dev/null and b/Assets/FluidBehaviorTree/Editor/Icons/Tasks/Cancel.png differ diff --git a/Assets/FluidBehaviorTree/Editor/Icons/Tasks/Cancel.png.meta b/Assets/FluidBehaviorTree/Editor/Icons/Tasks/Cancel.png.meta new file mode 100644 index 00000000..7375b53c --- /dev/null +++ b/Assets/FluidBehaviorTree/Editor/Icons/Tasks/Cancel.png.meta @@ -0,0 +1,101 @@ +fileFormatVersion: 2 +guid: cb5bf02779d4e2c49b4d7e4c8b08b766 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 10 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: 1 + mipBias: -100 + wrapU: 1 + wrapV: 1 + wrapW: -1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 1 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - serializedVersion: 2 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - serializedVersion: 2 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: 6c8fe32a12039c74082ab1a9fec1ab44 + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/FluidBehaviorTree/Editor/Icons/Tasks/Checkmark.png b/Assets/FluidBehaviorTree/Editor/Icons/Tasks/Checkmark.png new file mode 100644 index 00000000..359293b0 Binary files /dev/null and b/Assets/FluidBehaviorTree/Editor/Icons/Tasks/Checkmark.png differ diff --git a/Assets/FluidBehaviorTree/Editor/Icons/Tasks/Checkmark.png.meta b/Assets/FluidBehaviorTree/Editor/Icons/Tasks/Checkmark.png.meta new file mode 100644 index 00000000..1a47e8b5 --- /dev/null +++ b/Assets/FluidBehaviorTree/Editor/Icons/Tasks/Checkmark.png.meta @@ -0,0 +1,101 @@ +fileFormatVersion: 2 +guid: 85464217a3a1c6d4fa8d0c6bbaa10ae1 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 10 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: 1 + mipBias: -100 + wrapU: 1 + wrapV: 1 + wrapW: -1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 1 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - serializedVersion: 2 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - serializedVersion: 2 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: 92e06451cc527ac4daa48bd23f41cec5 + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/FluidBehaviorTree/Editor/Icons/Tasks/CompareArrows.png b/Assets/FluidBehaviorTree/Editor/Icons/Tasks/CompareArrows.png new file mode 100644 index 00000000..6a71801f Binary files /dev/null and b/Assets/FluidBehaviorTree/Editor/Icons/Tasks/CompareArrows.png differ diff --git a/Assets/FluidBehaviorTree/Editor/Icons/Tasks/CompareArrows.png.meta b/Assets/FluidBehaviorTree/Editor/Icons/Tasks/CompareArrows.png.meta new file mode 100644 index 00000000..d7a4eeca --- /dev/null +++ b/Assets/FluidBehaviorTree/Editor/Icons/Tasks/CompareArrows.png.meta @@ -0,0 +1,101 @@ +fileFormatVersion: 2 +guid: b570e0c12da15934b83750f4b4ddfdc2 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 10 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: 1 + mipBias: -100 + wrapU: 1 + wrapV: 1 + wrapW: -1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 1 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - serializedVersion: 2 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - serializedVersion: 2 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: 1be9cd5377551a94ea7d58a6065ffda1 + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/FluidBehaviorTree/Editor/Icons/Tasks/DownArrow.png b/Assets/FluidBehaviorTree/Editor/Icons/Tasks/DownArrow.png new file mode 100644 index 00000000..0a6f1ab0 Binary files /dev/null and b/Assets/FluidBehaviorTree/Editor/Icons/Tasks/DownArrow.png differ diff --git a/Assets/FluidBehaviorTree/Editor/Icons/Tasks/DownArrow.png.meta b/Assets/FluidBehaviorTree/Editor/Icons/Tasks/DownArrow.png.meta new file mode 100644 index 00000000..cce220c0 --- /dev/null +++ b/Assets/FluidBehaviorTree/Editor/Icons/Tasks/DownArrow.png.meta @@ -0,0 +1,101 @@ +fileFormatVersion: 2 +guid: 0dee0915e1ae2784b80346e10744d1e0 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 10 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: 1 + mipBias: -100 + wrapU: 1 + wrapV: 1 + wrapW: -1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 1 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - serializedVersion: 2 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - serializedVersion: 2 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: b5c8da1564a251c4c93cd6bad8eacd01 + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/FluidBehaviorTree/Editor/Icons/Tasks/Hourglass.png b/Assets/FluidBehaviorTree/Editor/Icons/Tasks/Hourglass.png new file mode 100644 index 00000000..b55f7894 Binary files /dev/null and b/Assets/FluidBehaviorTree/Editor/Icons/Tasks/Hourglass.png differ diff --git a/Assets/FluidBehaviorTree/Editor/Icons/Tasks/Hourglass.png.meta b/Assets/FluidBehaviorTree/Editor/Icons/Tasks/Hourglass.png.meta new file mode 100644 index 00000000..aa7b52dc --- /dev/null +++ b/Assets/FluidBehaviorTree/Editor/Icons/Tasks/Hourglass.png.meta @@ -0,0 +1,101 @@ +fileFormatVersion: 2 +guid: 969aaed97bed350429baeb26671b4e8b +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 10 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: 1 + mipBias: -100 + wrapU: 1 + wrapV: 1 + wrapW: -1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 1 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - serializedVersion: 2 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - serializedVersion: 2 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: 130db6902cddd144084d4449a7fefc11 + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/FluidBehaviorTree/Editor/Icons/Tasks/HourglassFill.png b/Assets/FluidBehaviorTree/Editor/Icons/Tasks/HourglassFill.png new file mode 100644 index 00000000..928b9b94 Binary files /dev/null and b/Assets/FluidBehaviorTree/Editor/Icons/Tasks/HourglassFill.png differ diff --git a/Assets/FluidBehaviorTree/Editor/Icons/Tasks/HourglassFill.png.meta b/Assets/FluidBehaviorTree/Editor/Icons/Tasks/HourglassFill.png.meta new file mode 100644 index 00000000..fe09c69a --- /dev/null +++ b/Assets/FluidBehaviorTree/Editor/Icons/Tasks/HourglassFill.png.meta @@ -0,0 +1,101 @@ +fileFormatVersion: 2 +guid: 320910a1f477bc04d9479b99dd7716cf +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 10 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: 1 + mipBias: -100 + wrapU: 1 + wrapV: 1 + wrapW: -1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 1 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - serializedVersion: 2 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - serializedVersion: 2 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: bdd9258c13cb80e4a8457e2b5edd02c3 + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/FluidBehaviorTree/Editor/Icons/Tasks/Invert.png b/Assets/FluidBehaviorTree/Editor/Icons/Tasks/Invert.png new file mode 100644 index 00000000..6195c1eb Binary files /dev/null and b/Assets/FluidBehaviorTree/Editor/Icons/Tasks/Invert.png differ diff --git a/Assets/FluidBehaviorTree/Editor/Icons/Tasks/Invert.png.meta b/Assets/FluidBehaviorTree/Editor/Icons/Tasks/Invert.png.meta new file mode 100644 index 00000000..ff0e4969 --- /dev/null +++ b/Assets/FluidBehaviorTree/Editor/Icons/Tasks/Invert.png.meta @@ -0,0 +1,101 @@ +fileFormatVersion: 2 +guid: 6876528cd31ee2942a0371402c4a1600 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 10 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: 1 + mipBias: -100 + wrapU: 1 + wrapV: 1 + wrapW: -1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 1 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - serializedVersion: 2 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - serializedVersion: 2 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: 955ea432af29a824db5811682144ae48 + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/FluidBehaviorTree/Editor/Icons/Tasks/LinearScale.png b/Assets/FluidBehaviorTree/Editor/Icons/Tasks/LinearScale.png new file mode 100644 index 00000000..3f97134f Binary files /dev/null and b/Assets/FluidBehaviorTree/Editor/Icons/Tasks/LinearScale.png differ diff --git a/Assets/FluidBehaviorTree/Editor/Icons/Tasks/LinearScale.png.meta b/Assets/FluidBehaviorTree/Editor/Icons/Tasks/LinearScale.png.meta new file mode 100644 index 00000000..16361b64 --- /dev/null +++ b/Assets/FluidBehaviorTree/Editor/Icons/Tasks/LinearScale.png.meta @@ -0,0 +1,101 @@ +fileFormatVersion: 2 +guid: 993b8bc8faf246f44b23ed381cece902 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 10 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: 1 + mipBias: -100 + wrapU: 1 + wrapV: 1 + wrapW: -1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 1 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - serializedVersion: 2 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - serializedVersion: 2 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: fa1aec5d1a271dc4facb21e4d386db46 + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/FluidBehaviorTree/Editor/Icons/Tasks/Play.png b/Assets/FluidBehaviorTree/Editor/Icons/Tasks/Play.png new file mode 100644 index 00000000..9248244a Binary files /dev/null and b/Assets/FluidBehaviorTree/Editor/Icons/Tasks/Play.png differ diff --git a/Assets/FluidBehaviorTree/Editor/Icons/Tasks/Play.png.meta b/Assets/FluidBehaviorTree/Editor/Icons/Tasks/Play.png.meta new file mode 100644 index 00000000..68d1a8af --- /dev/null +++ b/Assets/FluidBehaviorTree/Editor/Icons/Tasks/Play.png.meta @@ -0,0 +1,101 @@ +fileFormatVersion: 2 +guid: 0e5c5d00469150742b300b08ab569782 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 10 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: 1 + mipBias: -100 + wrapU: 1 + wrapV: 1 + wrapW: -1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 1 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - serializedVersion: 2 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - serializedVersion: 2 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: 4e69265ed6afb6147b1aeb3a25919eb1 + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/FluidBehaviorTree/Editor/Icons/Tasks/Question.png b/Assets/FluidBehaviorTree/Editor/Icons/Tasks/Question.png new file mode 100644 index 00000000..014f42ab Binary files /dev/null and b/Assets/FluidBehaviorTree/Editor/Icons/Tasks/Question.png differ diff --git a/Assets/FluidBehaviorTree/Editor/Icons/Tasks/Question.png.meta b/Assets/FluidBehaviorTree/Editor/Icons/Tasks/Question.png.meta new file mode 100644 index 00000000..9129bc45 --- /dev/null +++ b/Assets/FluidBehaviorTree/Editor/Icons/Tasks/Question.png.meta @@ -0,0 +1,101 @@ +fileFormatVersion: 2 +guid: be6488cc899d9cd4b83d231ef607aa42 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 10 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: 1 + mipBias: -100 + wrapU: 1 + wrapV: 1 + wrapW: -1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 1 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - serializedVersion: 2 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - serializedVersion: 2 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: e92118a583d3b664eae90c385568119f + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/FluidBehaviorTree/Editor/Icons/Tasks/RightArrow.png b/Assets/FluidBehaviorTree/Editor/Icons/Tasks/RightArrow.png new file mode 100644 index 00000000..a18f11aa Binary files /dev/null and b/Assets/FluidBehaviorTree/Editor/Icons/Tasks/RightArrow.png differ diff --git a/Assets/FluidBehaviorTree/Editor/Icons/Tasks/RightArrow.png.meta b/Assets/FluidBehaviorTree/Editor/Icons/Tasks/RightArrow.png.meta new file mode 100644 index 00000000..e83fd93c --- /dev/null +++ b/Assets/FluidBehaviorTree/Editor/Icons/Tasks/RightArrow.png.meta @@ -0,0 +1,101 @@ +fileFormatVersion: 2 +guid: 5ad2a3ea6f9399e41839a031ba97c4b9 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 10 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: 1 + mipBias: -100 + wrapU: 1 + wrapV: 1 + wrapW: -1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 1 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - serializedVersion: 2 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - serializedVersion: 2 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: 1ea78c7e96cc820498c8cc46a87a1924 + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/FluidBehaviorTree/Runtime/BehaviorTree/BehaviorTree.cs b/Assets/FluidBehaviorTree/Runtime/BehaviorTree/BehaviorTree.cs index b1e75ffa..460db7e2 100644 --- a/Assets/FluidBehaviorTree/Runtime/BehaviorTree/BehaviorTree.cs +++ b/Assets/FluidBehaviorTree/Runtime/BehaviorTree/BehaviorTree.cs @@ -5,18 +5,22 @@ namespace CleverCrow.Fluid.BTs.Trees { public interface IBehaviorTree { + string Name { get; } + TaskRoot Root { get; } int TickCount { get; } void AddActiveTask (ITask task); void RemoveActiveTask (ITask task); } + [System.Serializable] public class BehaviorTree : IBehaviorTree { private readonly GameObject _owner; private readonly List _tasks = new List(); public int TickCount { get; private set; } + public string Name { get; set; } public TaskRoot Root { get; } = new TaskRoot(); public IReadOnlyList ActiveTasks => _tasks; diff --git a/Assets/FluidBehaviorTree/Runtime/BehaviorTree/Builder/BehaviorTreeBuilder.cs b/Assets/FluidBehaviorTree/Runtime/BehaviorTree/Builder/BehaviorTreeBuilder.cs index d184e8b8..ce57b1a1 100644 --- a/Assets/FluidBehaviorTree/Runtime/BehaviorTree/Builder/BehaviorTreeBuilder.cs +++ b/Assets/FluidBehaviorTree/Runtime/BehaviorTree/Builder/BehaviorTreeBuilder.cs @@ -24,6 +24,16 @@ public BehaviorTreeBuilder (GameObject owner) { _pointers.Add(_tree.Root); } + /// + /// Set a name for the tree manually. For debugging purposes and visualizer window naming + /// + /// + /// + public BehaviorTreeBuilder Name (string name) { + _tree.Name = name; + return this; + } + public BehaviorTreeBuilder ParentTask

(string name) where P : ITaskParent, new() { var parent = new P { Name = name }; diff --git a/Assets/FluidBehaviorTree/Runtime/Decorators/DecoratorBase.cs b/Assets/FluidBehaviorTree/Runtime/Decorators/DecoratorBase.cs index 81e4d4c7..19b02376 100644 --- a/Assets/FluidBehaviorTree/Runtime/Decorators/DecoratorBase.cs +++ b/Assets/FluidBehaviorTree/Runtime/Decorators/DecoratorBase.cs @@ -5,7 +5,7 @@ using UnityEngine; namespace CleverCrow.Fluid.BTs.Decorators { - public abstract class DecoratorBase : ITaskParent { + public abstract class DecoratorBase : GenericTaskBase, ITaskParent { public List Children { get; } = new List(); public string Name { get; set; } @@ -18,7 +18,8 @@ public abstract class DecoratorBase : ITaskParent { public ITask Child => Children.Count > 0 ? Children[0] : null; - public TaskStatus Update () { + public override TaskStatus Update () { + base.Update(); var status = OnUpdate(); LastStatus = status; diff --git a/Assets/FluidBehaviorTree/Runtime/Decorators/Inverter.cs b/Assets/FluidBehaviorTree/Runtime/Decorators/Inverter.cs index 2120d7aa..56d13308 100644 --- a/Assets/FluidBehaviorTree/Runtime/Decorators/Inverter.cs +++ b/Assets/FluidBehaviorTree/Runtime/Decorators/Inverter.cs @@ -2,6 +2,8 @@ namespace CleverCrow.Fluid.BTs.Decorators { public class Inverter : DecoratorBase { + public override string IconPath { get; } = $"{PACKAGE_ROOT}/Invert.png"; + protected override TaskStatus OnUpdate () { if (Child == null) { return TaskStatus.Success; diff --git a/Assets/FluidBehaviorTree/Runtime/Decorators/ReturnFailure.cs b/Assets/FluidBehaviorTree/Runtime/Decorators/ReturnFailure.cs index c5d7b59d..9d52bc72 100644 --- a/Assets/FluidBehaviorTree/Runtime/Decorators/ReturnFailure.cs +++ b/Assets/FluidBehaviorTree/Runtime/Decorators/ReturnFailure.cs @@ -2,6 +2,8 @@ namespace CleverCrow.Fluid.BTs.Decorators { public class ReturnFailure : DecoratorBase { + public override string IconPath { get; } = $"{PACKAGE_ROOT}/Cancel.png"; + protected override TaskStatus OnUpdate () { var status = Child.Update(); if (status == TaskStatus.Continue) { diff --git a/Assets/FluidBehaviorTree/Runtime/Decorators/ReturnSuccess.cs b/Assets/FluidBehaviorTree/Runtime/Decorators/ReturnSuccess.cs index cbb907b4..7b90b930 100644 --- a/Assets/FluidBehaviorTree/Runtime/Decorators/ReturnSuccess.cs +++ b/Assets/FluidBehaviorTree/Runtime/Decorators/ReturnSuccess.cs @@ -2,6 +2,8 @@ namespace CleverCrow.Fluid.BTs.Decorators { public class ReturnSuccess : DecoratorBase { + public override string IconPath { get; } = $"{PACKAGE_ROOT}/Checkmark.png"; + protected override TaskStatus OnUpdate () { var status = Child.Update(); if (status == TaskStatus.Continue) { diff --git a/Assets/FluidBehaviorTree/Runtime/TaskParents/Composites/Parallel.cs b/Assets/FluidBehaviorTree/Runtime/TaskParents/Composites/Parallel.cs index 3b31a0c8..96b5325d 100644 --- a/Assets/FluidBehaviorTree/Runtime/TaskParents/Composites/Parallel.cs +++ b/Assets/FluidBehaviorTree/Runtime/TaskParents/Composites/Parallel.cs @@ -5,6 +5,8 @@ namespace CleverCrow.Fluid.BTs.TaskParents.Composites { public class Parallel : CompositeBase { private readonly Dictionary _childStatus = new Dictionary(); + public override string IconPath { get; } = $"{PACKAGE_ROOT}/CompareArrows.png"; + protected override TaskStatus OnUpdate () { var successCount = 0; var failureCount = 0; diff --git a/Assets/FluidBehaviorTree/Runtime/TaskParents/Composites/Selector.cs b/Assets/FluidBehaviorTree/Runtime/TaskParents/Composites/Selector.cs index bff7c823..0949bab2 100644 --- a/Assets/FluidBehaviorTree/Runtime/TaskParents/Composites/Selector.cs +++ b/Assets/FluidBehaviorTree/Runtime/TaskParents/Composites/Selector.cs @@ -1,8 +1,9 @@ -using System.Collections.Generic; -using CleverCrow.Fluid.BTs.Tasks; +using CleverCrow.Fluid.BTs.Tasks; namespace CleverCrow.Fluid.BTs.TaskParents.Composites { public class Selector : CompositeBase { + public override string IconPath { get; } = $"{PACKAGE_ROOT}/LinearScale.png"; + protected override TaskStatus OnUpdate () { for (var i = ChildIndex; i < Children.Count; i++) { var child = Children[ChildIndex]; diff --git a/Assets/FluidBehaviorTree/Runtime/TaskParents/Composites/SelectorRandom.cs b/Assets/FluidBehaviorTree/Runtime/TaskParents/Composites/SelectorRandom.cs index 9754a332..891783eb 100644 --- a/Assets/FluidBehaviorTree/Runtime/TaskParents/Composites/SelectorRandom.cs +++ b/Assets/FluidBehaviorTree/Runtime/TaskParents/Composites/SelectorRandom.cs @@ -8,6 +8,8 @@ namespace CleverCrow.Fluid.BTs.TaskParents.Composites { public class SelectorRandom : CompositeBase { private bool _init; + public override string IconPath { get; } = $"{PACKAGE_ROOT}/LinearScale.png"; + protected override TaskStatus OnUpdate () { if (!_init) { ShuffleChildren(); diff --git a/Assets/FluidBehaviorTree/Runtime/TaskParents/Composites/Sequence.cs b/Assets/FluidBehaviorTree/Runtime/TaskParents/Composites/Sequence.cs index 4c2e8bfb..d3fee3cc 100644 --- a/Assets/FluidBehaviorTree/Runtime/TaskParents/Composites/Sequence.cs +++ b/Assets/FluidBehaviorTree/Runtime/TaskParents/Composites/Sequence.cs @@ -2,6 +2,8 @@ namespace CleverCrow.Fluid.BTs.TaskParents.Composites { public class Sequence : CompositeBase { + public override string IconPath { get; } = $"{PACKAGE_ROOT}/RightArrow.png"; + protected override TaskStatus OnUpdate () { for (var i = ChildIndex; i < Children.Count; i++) { var child = Children[ChildIndex]; diff --git a/Assets/FluidBehaviorTree/Runtime/TaskParents/ITaskParent.cs b/Assets/FluidBehaviorTree/Runtime/TaskParents/ITaskParent.cs index 6dfe77fb..727c9b98 100644 --- a/Assets/FluidBehaviorTree/Runtime/TaskParents/ITaskParent.cs +++ b/Assets/FluidBehaviorTree/Runtime/TaskParents/ITaskParent.cs @@ -1,9 +1,7 @@ -using System.Collections.Generic; -using CleverCrow.Fluid.BTs.Tasks; +using CleverCrow.Fluid.BTs.Tasks; namespace CleverCrow.Fluid.BTs.TaskParents { public interface ITaskParent : ITask { - List Children { get; } ITaskParent AddChild (ITask child); } } \ No newline at end of file diff --git a/Assets/FluidBehaviorTree/Runtime/TaskParents/TaskParentBase.cs b/Assets/FluidBehaviorTree/Runtime/TaskParents/TaskParentBase.cs index 4aef9d10..1033777c 100644 --- a/Assets/FluidBehaviorTree/Runtime/TaskParents/TaskParentBase.cs +++ b/Assets/FluidBehaviorTree/Runtime/TaskParents/TaskParentBase.cs @@ -4,11 +4,13 @@ using UnityEngine; namespace CleverCrow.Fluid.BTs.TaskParents { - public abstract class TaskParentBase : ITaskParent { + public abstract class TaskParentBase : GenericTaskBase, ITaskParent { + private int _lastTickCount; + public IBehaviorTree ParentTree { get; set; } public TaskStatus LastStatus { get; private set; } - public string Name { get; set; } + public virtual string Name { get; set; } public bool Enabled { get; set; } = true; public List Children { get; } = new List(); @@ -17,9 +19,8 @@ public abstract class TaskParentBase : ITaskParent { public GameObject Owner { get; set; } - private int _lastTickCount; - - public TaskStatus Update () { + public override TaskStatus Update () { + base.Update(); UpdateTicks(); var status = OnUpdate(); diff --git a/Assets/FluidBehaviorTree/Runtime/TaskParents/TaskRoot.cs b/Assets/FluidBehaviorTree/Runtime/TaskParents/TaskRoot.cs index 923754fb..c96a7c2b 100644 --- a/Assets/FluidBehaviorTree/Runtime/TaskParents/TaskRoot.cs +++ b/Assets/FluidBehaviorTree/Runtime/TaskParents/TaskRoot.cs @@ -2,7 +2,9 @@ namespace CleverCrow.Fluid.BTs.TaskParents { public class TaskRoot : TaskParentBase { + public override string Name { get; set; } = "Root"; protected override int MaxChildren { get; } = 1; + public override string IconPath { get; } = $"{PACKAGE_ROOT}/DownArrow.png"; protected override TaskStatus OnUpdate () { if (Children.Count == 0) { diff --git a/Assets/FluidBehaviorTree/Runtime/Tasks/Actions/Wait.cs b/Assets/FluidBehaviorTree/Runtime/Tasks/Actions/Wait.cs index 99e0df64..7d8707d3 100644 --- a/Assets/FluidBehaviorTree/Runtime/Tasks/Actions/Wait.cs +++ b/Assets/FluidBehaviorTree/Runtime/Tasks/Actions/Wait.cs @@ -3,6 +3,8 @@ public class Wait : ActionBase { public int turns = 1; private int _ticks; + + public override string IconPath { get; } = $"{PACKAGE_ROOT}/HourglassFill.png"; protected override void OnStart () { _ticks = 0; diff --git a/Assets/FluidBehaviorTree/Runtime/Tasks/Actions/WaitTime/WaitTime.cs b/Assets/FluidBehaviorTree/Runtime/Tasks/Actions/WaitTime/WaitTime.cs index 4dd10f0b..f9cb26a6 100644 --- a/Assets/FluidBehaviorTree/Runtime/Tasks/Actions/WaitTime/WaitTime.cs +++ b/Assets/FluidBehaviorTree/Runtime/Tasks/Actions/WaitTime/WaitTime.cs @@ -8,6 +8,7 @@ public class WaitTime : ActionBase { public float time = 1; + public override string IconPath { get; } = $"{PACKAGE_ROOT}/Hourglass.png"; public WaitTime (ITimeMonitor timeMonitor) { _timeMonitor = timeMonitor; diff --git a/Assets/FluidBehaviorTree/Runtime/Tasks/Conditions/ConditionBase.cs b/Assets/FluidBehaviorTree/Runtime/Tasks/Conditions/ConditionBase.cs index 140233f2..5f2fc900 100644 --- a/Assets/FluidBehaviorTree/Runtime/Tasks/Conditions/ConditionBase.cs +++ b/Assets/FluidBehaviorTree/Runtime/Tasks/Conditions/ConditionBase.cs @@ -1,5 +1,8 @@ namespace CleverCrow.Fluid.BTs.Tasks { public abstract class ConditionBase : TaskBase { + public override string IconPath { get; } = $"{PACKAGE_ROOT}/Question.png"; + public override float IconPadding => 10; + protected abstract bool OnUpdate (); protected override TaskStatus GetUpdate () { diff --git a/Assets/FluidBehaviorTree/Runtime/Tasks/EditorRuntimeUtilities.cs b/Assets/FluidBehaviorTree/Runtime/Tasks/EditorRuntimeUtilities.cs new file mode 100644 index 00000000..96cd5423 --- /dev/null +++ b/Assets/FluidBehaviorTree/Runtime/Tasks/EditorRuntimeUtilities.cs @@ -0,0 +1,11 @@ +using UnityEngine.Events; + +namespace CleverCrow.Fluid.BTs.Tasks { + ///

+ /// A bundle of editor utilities that are for data visualization only. + /// Unsafe to call outside of #if UNITY_EDITOR methods and non-performant for normal runtime + /// + public class EditorRuntimeUtilities { + public readonly UnityEvent EventActive = new UnityEvent(); + } +} \ No newline at end of file diff --git a/Assets/FluidBehaviorTree/Runtime/Tasks/EditorRuntimeUtilities.cs.meta b/Assets/FluidBehaviorTree/Runtime/Tasks/EditorRuntimeUtilities.cs.meta new file mode 100644 index 00000000..b92047bd --- /dev/null +++ b/Assets/FluidBehaviorTree/Runtime/Tasks/EditorRuntimeUtilities.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 76bee382a9b84e269ca86ac64b03579a +timeCreated: 1559958239 \ No newline at end of file diff --git a/Assets/FluidBehaviorTree/Runtime/Tasks/GenericTaskBase.cs b/Assets/FluidBehaviorTree/Runtime/Tasks/GenericTaskBase.cs new file mode 100644 index 00000000..b0f32ad5 --- /dev/null +++ b/Assets/FluidBehaviorTree/Runtime/Tasks/GenericTaskBase.cs @@ -0,0 +1,28 @@ +namespace CleverCrow.Fluid.BTs.Tasks { + public abstract class GenericTaskBase { + private EditorRuntimeUtilities _editorUtils; + protected const string PACKAGE_ROOT = "ROOT/Editor/Icons/Tasks"; + + /// + /// For custom project icons provide a path from assets to a Texture2D asset. Example `Assets/MyIcon.png`. + /// Be sure to NOT include the keyword `ROOT` in your path name. This will be replaced with a path + /// to the package root for Fluid Behavior Tree. + /// + public virtual string IconPath => $"{PACKAGE_ROOT}/Play.png"; + public virtual float IconPadding { get; } + public bool HasBeenActive { get; private set; } + + public EditorRuntimeUtilities EditorUtils => + _editorUtils ?? (_editorUtils = new EditorRuntimeUtilities()); + + public virtual TaskStatus Update () { +#if UNITY_EDITOR + EditorUtils.EventActive.Invoke(); +#endif + + HasBeenActive = true; + + return TaskStatus.Success; + } + } +} diff --git a/Assets/FluidBehaviorTree/Runtime/Tasks/GenericTaskBase.cs.meta b/Assets/FluidBehaviorTree/Runtime/Tasks/GenericTaskBase.cs.meta new file mode 100644 index 00000000..0b251b7d --- /dev/null +++ b/Assets/FluidBehaviorTree/Runtime/Tasks/GenericTaskBase.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 2c8d660631584556aef2d9f4441474d7 +timeCreated: 1559958724 \ No newline at end of file diff --git a/Assets/FluidBehaviorTree/Runtime/Tasks/ITask.cs b/Assets/FluidBehaviorTree/Runtime/Tasks/ITask.cs index edc58145..094689e0 100644 --- a/Assets/FluidBehaviorTree/Runtime/Tasks/ITask.cs +++ b/Assets/FluidBehaviorTree/Runtime/Tasks/ITask.cs @@ -1,4 +1,5 @@ -using CleverCrow.Fluid.BTs.Trees; +using System.Collections.Generic; +using CleverCrow.Fluid.BTs.Trees; using UnityEngine; namespace CleverCrow.Fluid.BTs.Tasks { @@ -13,6 +14,8 @@ public interface ITask { /// bool Enabled { get; set; } + string IconPath { get; } + /// /// Reference to the behavior tree responsible for this node. Allows for dynamic variables such as adding a /// GameObject reference @@ -23,11 +26,17 @@ public interface ITask { /// Tree this node belongs to /// IBehaviorTree ParentTree { get; set; } + + List Children { get; } /// /// Last status returned by Update /// TaskStatus LastStatus { get; } + + EditorRuntimeUtilities EditorUtils { get; } + float IconPadding { get; } + bool HasBeenActive { get; } /// /// Triggered every tick diff --git a/Assets/FluidBehaviorTree/Runtime/Tasks/TaskBase.cs b/Assets/FluidBehaviorTree/Runtime/Tasks/TaskBase.cs index 2e1c71c9..86ecc0f2 100644 --- a/Assets/FluidBehaviorTree/Runtime/Tasks/TaskBase.cs +++ b/Assets/FluidBehaviorTree/Runtime/Tasks/TaskBase.cs @@ -1,8 +1,9 @@ -using CleverCrow.Fluid.BTs.Trees; +using System.Collections.Generic; +using CleverCrow.Fluid.BTs.Trees; using UnityEngine; namespace CleverCrow.Fluid.BTs.Tasks { - public abstract class TaskBase : ITask { + public abstract class TaskBase : GenericTaskBase, ITask { private bool _init; private bool _start; private bool _exit; @@ -14,9 +15,11 @@ public abstract class TaskBase : ITask { public GameObject Owner { get; set; } public IBehaviorTree ParentTree { get; set; } + public List Children { get; } = null; public TaskStatus LastStatus { get; private set; } - public TaskStatus Update () { + public override TaskStatus Update () { + base.Update(); UpdateTicks(); if (!_init) { diff --git a/Assets/FluidBehaviorTree/Tests/Editor/BehaviorTrees/Containers.meta b/Assets/FluidBehaviorTree/Tests/Editor/BehaviorTrees/Containers.meta new file mode 100644 index 00000000..e59dddb6 --- /dev/null +++ b/Assets/FluidBehaviorTree/Tests/Editor/BehaviorTrees/Containers.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 45f763df50a04d83b540f901a2e3a387 +timeCreated: 1559835412 \ No newline at end of file diff --git a/Assets/FluidBehaviorTree/Tests/Editor/BehaviorTrees/Containers/GraphContainerHorizontalTest.cs b/Assets/FluidBehaviorTree/Tests/Editor/BehaviorTrees/Containers/GraphContainerHorizontalTest.cs new file mode 100644 index 00000000..478da982 --- /dev/null +++ b/Assets/FluidBehaviorTree/Tests/Editor/BehaviorTrees/Containers/GraphContainerHorizontalTest.cs @@ -0,0 +1,206 @@ +using CleverCrow.Fluid.BTs.Testing; +using NSubstitute; +using NUnit.Framework; + +namespace CleverCrow.Fluid.BTs.Trees.Editors { + public class GraphContainerHorizontalTest { + private GraphContainerHorizontal _container; + private IGraphBox _childBox; + + [SetUp] + public void BeforeEach () { + _container = new GraphContainerHorizontal(); + _childBox = A.GraphBoxStub().WithSize(100, 50).Build(); + } + + public class AddBoxMethod { + public class DefaultTests : GraphContainerHorizontalTest { + [Test] + public void It_should_add_a_child_container () { + _container.AddBox(_childBox); + + Assert.IsTrue(_container.ChildContainers.Contains(_childBox)); + } + + [Test] + public void It_should_set_the_local_position_of_a_child_box () { + _container.AddBox(_childBox); + + _childBox.Received(1).SetLocalPosition(0, 0); + } + + [Test] + public void It_should_stack_multiple_child_containers_side_by_side () { + for (var i = 0; i < 3; i++) { + var child = A.GraphBoxStub().WithSize(100, 50).Build(); + _container.AddBox(child); + } + + for (var i = 0; i < _container.ChildContainers.Count; i++) { + var child = _container.ChildContainers[i]; + child.Received(1).SetLocalPosition(100f * i, 0); + } + } + + [Test] + public void It_should_update_Width_when_a_new_child_container_is_added () { + _container.AddBox(_childBox); + + Assert.AreEqual(100f, _container.Width); + } + } + + public class SettingHeight : GraphContainerHorizontalTest { + [Test] + public void It_should_set_the_height_to_the_child () { + _container.AddBox(_childBox); + + Assert.AreEqual(50, _container.Height); + } + + [Test] + public void It_should_set_the_Height_if_the_next_child_is_larger () { + var childBoxAlt = A.GraphBoxStub().WithSize(0, 100).Build(); + + _container.AddBox(_childBox); + _container.AddBox(childBoxAlt); + + Assert.AreEqual(100, _container.Height); + } + + [Test] + public void It_should_not_set_the_Height_if_the_next_child_is_smaller () { + var childBoxAlt = A.GraphBoxStub().WithSize(0, 20).Build(); + + _container.AddBox(_childBox); + _container.AddBox(childBoxAlt); + + Assert.AreEqual(50, _container.Height); + } + } + + public class ItShouldUpdateGlobalPositioning : GraphContainerHorizontalTest { + [Test] + public void On_added_boxes () { + _container.SetGlobalPosition(50, 100); + + _container.AddBox(_childBox); + + _childBox.Received(1).AddGlobalPosition(50, 100); + } + + [Test] + public void On_nested_positions_on_added_boxes () { + var box = new GraphBox(); + box.SetSize(50, 50); + + var nestedContainer = new GraphContainerHorizontal(); + nestedContainer.AddBox(box); + + _container.SetGlobalPosition(50, 100); + _container.AddBox(nestedContainer); + + Assert.AreEqual(100, box.GlobalPositionY); + } + + [Test] + public void On_nested_child_positions_on_added_boxes () { + var boxA = new GraphBox(); + boxA.SetSize(50, 50); + + var boxB = new GraphBox(); + boxB.SetSize(50, 50); + + var nestedContainer = new GraphContainerHorizontal(); + nestedContainer.AddBox(boxA); + nestedContainer.AddBox(boxB); + + _container.SetGlobalPosition(50, 100); + _container.AddBox(nestedContainer); + + Assert.AreEqual(100, boxB.GlobalPositionX); + } + + [Test] + public void On_deeply_nested_child_positions_on_added_boxes () { + var boxA = new GraphBox(); + boxA.SetSize(50, 50); + + var boxB = new GraphBox(); + boxB.SetSize(50, 50); + + var nestedContainer = new GraphContainerHorizontal(); + nestedContainer.SetGlobalPosition(100, 50); + nestedContainer.AddBox(boxA); + nestedContainer.AddBox(boxB); + + _container.SetGlobalPosition(50, 100); + _container.AddBox(nestedContainer); + + Assert.AreEqual(200, boxB.GlobalPositionX); + } + } + } + + public class CenterAlignChildrenMethod : GraphContainerHorizontalTest { + [Test] + public void It_should_align_a_child_in_the_center () { + _childBox.Width.Returns(50); + + var children = new GraphContainerHorizontal(); + children.AddBox(A.GraphBoxStub().WithSize(50, 50).Build()); + children.AddBox(A.GraphBoxStub().WithSize(50, 50).Build()); + + var wrapper = new GraphContainerVertical(); + wrapper.AddBox(_childBox); + wrapper.AddBox(children); + + _container.AddBox(wrapper); + _container.CenterAlignChildren(); + + _childBox.Received(1).AddGlobalPosition(25, 0); + } + } + } + + public class BreakingExampleCases { + [Test] + public void Root_should_push_down_the_next_node () { + var tree = new GraphContainerVertical(); + tree.SetGlobalPosition(300, 0); + var nodeWrapper = new GraphContainerVertical(); + var box = new GraphBox(); + box.SetSize(50, 50); + var childrenContainer = new GraphContainerHorizontal(); + + var childWrapper = new GraphContainerVertical(); + var childBox = new GraphBox(); + childBox.SetSize(50, 50); + + nodeWrapper.AddBox(box); + Assert.AreEqual(50, nodeWrapper.Height); + Assert.AreEqual(50, nodeWrapper.Width); + Assert.AreEqual(0, box.GlobalPositionY); + + childWrapper.AddBox(childBox); + Assert.AreEqual(50, nodeWrapper.Height); + Assert.AreEqual(50, nodeWrapper.Width); + + childrenContainer.AddBox(childWrapper); + Assert.AreEqual(50, nodeWrapper.Height); + Assert.AreEqual(50, nodeWrapper.Width); + Assert.AreEqual(0, childrenContainer.GlobalPositionY); + + nodeWrapper.AddBox(childrenContainer); + Assert.AreEqual(100, nodeWrapper.Height); + Assert.AreEqual(50, nodeWrapper.Width); + Assert.AreEqual(50, childrenContainer.GlobalPositionY); + + tree.AddBox(nodeWrapper); + Assert.AreEqual(0, nodeWrapper.LocalPositionY); + Assert.AreEqual(0, nodeWrapper.GlobalPositionY); + Assert.AreEqual(50, childrenContainer.GlobalPositionY); + Assert.AreEqual(0, box.GlobalPositionY); + } + } +} \ No newline at end of file diff --git a/Assets/FluidBehaviorTree/Tests/Editor/BehaviorTrees/Containers/GraphContainerHorizontalTest.cs.meta b/Assets/FluidBehaviorTree/Tests/Editor/BehaviorTrees/Containers/GraphContainerHorizontalTest.cs.meta new file mode 100644 index 00000000..caf63e3c --- /dev/null +++ b/Assets/FluidBehaviorTree/Tests/Editor/BehaviorTrees/Containers/GraphContainerHorizontalTest.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: a3019c1968d14359b2a872b2a9415be0 +timeCreated: 1559776342 \ No newline at end of file diff --git a/Assets/FluidBehaviorTree/Tests/Editor/BehaviorTrees/GraphNodeTest.cs b/Assets/FluidBehaviorTree/Tests/Editor/BehaviorTrees/GraphNodeTest.cs new file mode 100644 index 00000000..a3b33609 --- /dev/null +++ b/Assets/FluidBehaviorTree/Tests/Editor/BehaviorTrees/GraphNodeTest.cs @@ -0,0 +1,192 @@ +using System.Collections.Generic; +using CleverCrow.Fluid.BTs.Tasks; +using CleverCrow.Fluid.BTs.Testing; +using NSubstitute; +using NUnit.Framework; +using UnityEngine; + +namespace CleverCrow.Fluid.BTs.Trees.Editors.Testing { + public class GraphNodeTest { + public class SetPositionMethod { + private IGraphNodePrinter _printer; + private Vector2 _size = new Vector2(50, 100); + + private GraphNode CreateNode (ITask task, GraphNodeOptions options = null) { + if (options == null) options = new GraphNodeOptions(); + options.Size = _size; + return new GraphNode(task, _printer, options); + } + + [SetUp] + public void BeforeEach () { + _printer = Substitute.For(); + } + + public class DefaultTests : SetPositionMethod { + [Test] + public void It_should_set_the_position () { + var task = A.TaskStub().Build(); + var graphNode = CreateNode(task); + + graphNode.SetPosition(Vector2.one); + + Assert.AreEqual(Vector2.one, graphNode.Position); + } + + + [Test] + public void It_should_offset_two_children_by_half_the_width () { + var task = A.TaskStub() + .SetChildren(new List { + A.TaskStub().Build(), + A.TaskStub().Build(), + }) + .Build(); + var graphNode = CreateNode(task); + var childA = graphNode.Children[0]; + var childB = graphNode.Children[1]; + var shiftAmount = graphNode.Size.x * 0.5f; + + graphNode.SetPosition(Vector2.zero); + + Assert.AreEqual(new Vector2(graphNode.Position.x - shiftAmount, graphNode.Size.y), childA.Position); + Assert.AreEqual(new Vector2(graphNode.Position.x + shiftAmount, graphNode.Size.y), childB.Position); + } + + [Test] + public void It_should_offset_three_children_to_line_up_in_the_middle () { + var task = A.TaskStub() + .SetChildren(new List { + A.TaskStub().Build(), + A.TaskStub().Build(), + A.TaskStub().Build(), + }) + .Build(); + var graphNode = CreateNode(task); + var childA = graphNode.Children[0]; + var childB = graphNode.Children[1]; + var childC = graphNode.Children[2]; + var shiftAmount = graphNode.Size.x * 1f; + + graphNode.SetPosition(Vector2.zero); + + Assert.AreEqual(new Vector2(graphNode.Position.x - shiftAmount, graphNode.Size.y), childA.Position); + Assert.AreEqual(new Vector2(graphNode.Position.x, graphNode.Size.y), childB.Position); + Assert.AreEqual(new Vector2(graphNode.Position.x + shiftAmount, graphNode.Size.y), childC.Position); + } + + [Test] + public void It_should_offset_four_children_to_line_up_in_the_middle () { + var task = A.TaskStub() + .SetChildren(new List { + A.TaskStub().Build(), + A.TaskStub().Build(), + A.TaskStub().Build(), + A.TaskStub().Build(), + }) + .Build(); + var graphNode = CreateNode(task); + var childA = graphNode.Children[0]; + var childB = graphNode.Children[1]; + var childC = graphNode.Children[2]; + var childD = graphNode.Children[3]; + var shiftAmount = graphNode.Size.x; + + graphNode.SetPosition(Vector2.zero); + + Assert.AreEqual(new Vector2(graphNode.Position.x - shiftAmount * 1.5f, graphNode.Size.y), + childA.Position); + Assert.AreEqual(new Vector2(graphNode.Position.x - shiftAmount * 0.5f, graphNode.Size.y), + childB.Position); + Assert.AreEqual(new Vector2(graphNode.Position.x + shiftAmount * 0.5f, graphNode.Size.y), + childC.Position); + Assert.AreEqual(new Vector2(graphNode.Position.x + shiftAmount * 1.5f, graphNode.Size.y), + childD.Position); + } + } + + public class SingleChildTests : SetPositionMethod { + private ITask _task; + + [SetUp] + public void BeforeEachTest () { + _task = A.TaskStub() + .SetChildren(new List {A.TaskStub().Build()}) + .Build(); + } + + [Test] + public void It_should_set_the_child_position_directly_below_the_parent () { + var graphNode = CreateNode(_task); + var child = graphNode.Children[0]; + + graphNode.SetPosition(Vector2.zero); + + Assert.AreEqual(new Vector2(0, graphNode.Size.y), child.Position); + } + + [Test] + public void It_should_set_the_child_position_below_a_vertical_connector_bottom () { + var graphNode = CreateNode(_task, new GraphNodeOptions { + VerticalConnectorBottomHeight = 10, + }); + var child = graphNode.Children[0]; + + graphNode.SetPosition(Vector2.zero); + + Assert.AreEqual( + new Vector2(0, graphNode.Size.y + graphNode.VerticalConnectorBottomHeight), + child.Position); + } + + [Test] + public void It_should_set_the_child_position_below_a_vertical_bottom_divider_plus_horizontal_line () { + var graphNode = CreateNode(_task, new GraphNodeOptions { + VerticalConnectorBottomHeight = 10, + HorizontalConnectorHeight = 1, + }); + var child = graphNode.Children[0]; + + graphNode.SetPosition(Vector2.zero); + + var expectedY = graphNode.Size.y + + graphNode.VerticalConnectorBottomHeight + + graphNode.HorizontalConnectorHeight; + + Assert.AreEqual(new Vector2(0, expectedY), child.Position); + } + + [Test] + public void It_should_set_the_child_position_below_a_vertical_connector_top () { + var graphNode = CreateNode(_task, new GraphNodeOptions { + VerticalConnectorBottomHeight = 10, + HorizontalConnectorHeight = 1, + VerticalConnectorTopHeight = 3, + }); + var child = graphNode.Children[0]; + + graphNode.SetPosition(Vector2.zero); + + var expectedY = graphNode.Size.y + + graphNode.VerticalConnectorBottomHeight + + graphNode.HorizontalConnectorHeight + + graphNode.VerticalConnectorTopHeight; + + Assert.AreEqual(new Vector2(0, expectedY), child.Position); + } + + [Test] + public void It_should_make_the_child_inherit_the_container_size () { + var graphNode = CreateNode(_task, new GraphNodeOptions { + VerticalConnectorBottomHeight = 10, + HorizontalConnectorHeight = 1, + VerticalConnectorTopHeight = 3, + }); + var child = graphNode.Children[0]; + + Assert.AreEqual(graphNode.ContainerHeight, child.ContainerHeight); + } + } + } + } +} \ No newline at end of file diff --git a/Assets/FluidBehaviorTree/Tests/Editor/BehaviorTrees/GraphNodeTest.cs.meta b/Assets/FluidBehaviorTree/Tests/Editor/BehaviorTrees/GraphNodeTest.cs.meta new file mode 100644 index 00000000..7d525e07 --- /dev/null +++ b/Assets/FluidBehaviorTree/Tests/Editor/BehaviorTrees/GraphNodeTest.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: f0bc28ba068f486bb360b51f441042e8 +timeCreated: 1559689316 \ No newline at end of file diff --git a/Assets/FluidBehaviorTree/Tests/Editor/BehaviorTrees/VisualTaskTest.cs b/Assets/FluidBehaviorTree/Tests/Editor/BehaviorTrees/VisualTaskTest.cs new file mode 100644 index 00000000..299b9c5b --- /dev/null +++ b/Assets/FluidBehaviorTree/Tests/Editor/BehaviorTrees/VisualTaskTest.cs @@ -0,0 +1,12 @@ +using NUnit.Framework; + +namespace FluidBehaviorTree.Tests.Editor.BehaviorTrees { + public class VisualTaskTest { + public class SetupMethod { + [Test] + public void It_should_add_itself_to_the_parent_container () { + + } + } + } +} \ No newline at end of file diff --git a/Assets/FluidBehaviorTree/Tests/Editor/BehaviorTrees/VisualTaskTest.cs.meta b/Assets/FluidBehaviorTree/Tests/Editor/BehaviorTrees/VisualTaskTest.cs.meta new file mode 100644 index 00000000..1216fd30 --- /dev/null +++ b/Assets/FluidBehaviorTree/Tests/Editor/BehaviorTrees/VisualTaskTest.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: bc948cb0126544cb9d5ed05d4c5acaf6 +timeCreated: 1559785283 \ No newline at end of file diff --git a/Assets/FluidBehaviorTree/Tests/Editor/Builders/A.cs b/Assets/FluidBehaviorTree/Tests/Editor/Builders/A.cs index 38b56aeb..4cc683e8 100644 --- a/Assets/FluidBehaviorTree/Tests/Editor/Builders/A.cs +++ b/Assets/FluidBehaviorTree/Tests/Editor/Builders/A.cs @@ -3,5 +3,9 @@ public static class A { public static TaskStubBuilder TaskStub () { return new TaskStubBuilder(); } + + public static GraphBoxStubBuilder GraphBoxStub () { + return new GraphBoxStubBuilder(); + } } } \ No newline at end of file diff --git a/Assets/FluidBehaviorTree/Tests/Editor/Builders/GraphBoxStubBuilder.cs b/Assets/FluidBehaviorTree/Tests/Editor/Builders/GraphBoxStubBuilder.cs new file mode 100644 index 00000000..511770ce --- /dev/null +++ b/Assets/FluidBehaviorTree/Tests/Editor/Builders/GraphBoxStubBuilder.cs @@ -0,0 +1,23 @@ +using CleverCrow.Fluid.BTs.Trees.Editors; +using NSubstitute; + +namespace CleverCrow.Fluid.BTs.Testing { + public class GraphBoxStubBuilder { + private float _width; + private float _height; + + public GraphBoxStubBuilder WithSize (float width, float height) { + _width = width; + _height = height; + return this; + } + + public IGraphBox Build () { + var task = Substitute.For(); + task.Width.Returns(_width); + task.Height.Returns(_height); + + return task; + } + } +} \ No newline at end of file diff --git a/Assets/FluidBehaviorTree/Tests/Editor/Builders/GraphBoxStubBuilder.cs.meta b/Assets/FluidBehaviorTree/Tests/Editor/Builders/GraphBoxStubBuilder.cs.meta new file mode 100644 index 00000000..9afcbb20 --- /dev/null +++ b/Assets/FluidBehaviorTree/Tests/Editor/Builders/GraphBoxStubBuilder.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: b9eb06d7d8894d63b52358b5ac1513d5 +timeCreated: 1559835441 \ No newline at end of file diff --git a/Assets/FluidBehaviorTree/Tests/Editor/Builders/TaskStubBuilder.cs b/Assets/FluidBehaviorTree/Tests/Editor/Builders/TaskStubBuilder.cs index d89413c4..ecd4b4f1 100644 --- a/Assets/FluidBehaviorTree/Tests/Editor/Builders/TaskStubBuilder.cs +++ b/Assets/FluidBehaviorTree/Tests/Editor/Builders/TaskStubBuilder.cs @@ -1,11 +1,12 @@ -using CleverCrow.Fluid.BTs.Tasks; +using System.Collections.Generic; +using CleverCrow.Fluid.BTs.Tasks; using NSubstitute; -using NSubstitute.ReturnsExtensions; namespace CleverCrow.Fluid.BTs.Testing { public class TaskStubBuilder { private bool _enabled = true; private TaskStatus _status = TaskStatus.Success; + private List _children; public TaskStubBuilder WithEnabled (bool enabled) { _enabled = enabled; @@ -18,11 +19,17 @@ public TaskStubBuilder WithUpdateStatus (TaskStatus status) { return this; } + + public TaskStubBuilder SetChildren (List children) { + _children = children; + return this; + } public ITask Build () { var task = Substitute.For(); task.Enabled.Returns(_enabled); task.Update().ReturnsForAnyArgs(_status); + task.Children.Returns(_children); return task; } diff --git a/Assets/FluidBehaviorTree/Tests/Editor/Fluid.BehaviorTree.EditorTests.asmdef b/Assets/FluidBehaviorTree/Tests/Editor/Fluid.BehaviorTree.EditorTests.asmdef index f7823a71..175a5845 100644 --- a/Assets/FluidBehaviorTree/Tests/Editor/Fluid.BehaviorTree.EditorTests.asmdef +++ b/Assets/FluidBehaviorTree/Tests/Editor/Fluid.BehaviorTree.EditorTests.asmdef @@ -1,7 +1,8 @@ { "name": "Fluid.BehaviorTree.EditorTests", "references": [ - "Fluid.BehaviorTree" + "Fluid.BehaviorTree", + "Fluid.BehaviorTree.Editor" ], "optionalUnityReferences": [ "TestAssemblies" diff --git a/README.md b/README.md index e9efda0b..4405dcea 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,7 @@ Inspired by Fluent Behavior Tree. * Extendable, write your own custom re-usable nodes * Pre-built library of tasks to kickstart your AI +* Tree visualizer to debug your trees at runtime * Heavily tested with TDD and unit tests * Tracks the last position of your behavior tree and restores it the next frame * Built for Unity (no integration overhead) @@ -20,29 +21,6 @@ See upcoming features and development progress on the [Trello Board](https://tre ## Getting Started -Fluid Behavior Tree is used through [Unity's Package Manager](https://docs.unity3d.com/Manual/CustomPackages.html). In order to use it you'll need to add the following lines to your `Packages/manifest.json` file. After that you'll be able to visually control what specific version of Fluid Behavior Tree you're using from the package manager window in Unity. This has to be done so your Unity editor can connect to NPM's package registry. - -```json -{ - "scopedRegistries": [ - { - "name": "NPM", - "url": "https://registry.npmjs.org", - "scopes": [ - "com.fluid" - ] - } - ], - "dependencies": { - "com.fluid.behavior-tree": "2.0.1" - } -} -``` - -Archives of specific versions and release notes are available on the [releases page](https://github.com/ashblue/fluid-behavior-tree/releases). - -### Creating a Behavior Tree - When creating trees you'll need to store them in a variable to properly cache all the necessary data. ```C# @@ -51,6 +29,7 @@ using CleverCrow.Fluid.BTs.Tasks; using CleverCrow.Fluid.BTs.Trees; public class MyCustomAi : MonoBehaviour { + [SerializeField] private BehaviorTree _tree; private void Awake () { @@ -81,6 +60,12 @@ Depending on what you return for a task status different things will happen. * Failure: Same as success, except informs that the node failed * Continue: Rerun this node the next time `tree.Tick()` is called. A pointer reference is tracked by the tree and can only be cleared if `tree.Reset()` is called. +### Tree Visualizer + +As long as your tree storage variable is set to `public` or has a `SerializeField` attribute. You'll be able to print a visualization of your tree while the game is running in the editor. Note that you cannot view trees while the game is not running. As the tree has to be built in order to be visualized. + +![Visualizer](tree-visualizer.png) + ### Extending Trees You can safely add new code to your behavior trees with several lines. Allowing you to customize BTs while supporting future version upgrades. @@ -114,9 +99,37 @@ public class ExampleUsage : MonoBehaviour { } ``` +### Installing + +Fluid Behavior Tree is used through [Unity's Package Manager](https://docs.unity3d.com/Manual/CustomPackages.html). In order to use it you'll need to add the following lines to your `Packages/manifest.json` file. After that you'll be able to visually control what specific version of Fluid Behavior Tree you're using from the package manager window in Unity. This has to be done so your Unity editor can connect to NPM's package registry. + +```json +{ + "scopedRegistries": [ + { + "name": "NPM", + "url": "https://registry.npmjs.org", + "scopes": [ + "com.fluid" + ] + } + ], + "dependencies": { + "com.fluid.behavior-tree": "2.0.1" + } +} +``` + +Archives of specific versions and release notes are available on the [releases page](https://github.com/ashblue/fluid-behavior-tree/releases). + +### Example Scene + +You might want to look at the [capture the flag](https://github.com/ashblue/fluid-behavior-tree-ctf-example) example project +for a working example of how Fluid Behavior Tree can be used in your project. It demonstrates real time usage +with units who attempt to capture the flag while grabbing power ups to try and gain the upper hand. + ## Table of Contents - * [Example Scene](#example-scene) * [Library](#library) + [Actions](#actions) - [Generic](#action-generic) @@ -145,12 +158,6 @@ public class ExampleUsage : MonoBehaviour { * [Development Environment](#development-environment) * [Submitting your own actions, conditions, ect](#submitting-code-to-this-project) -## Example Scene - -You might want to look at the [capture the flag](https://github.com/ashblue/fluid-behavior-tree-ctf-example) example project -for a working example of how Fluid Behavior Tree can be used in your project. It demonstrates real time usage -with units who attempt to capture the flag while grabbing power ups to try and gain the upper hand. - ## Library Fluid Behavior Tree comes with a robust library of pre-made actions, conditions, composites, and other nodes diff --git a/tree-visualizer.png b/tree-visualizer.png new file mode 100644 index 00000000..5466f973 Binary files /dev/null and b/tree-visualizer.png differ