Пример #1
0
    void AddTaskToAssets(BehaviourTreeExecutionNode node, BehaviourTreeTask oldTaskToRemove)
    {
        if (oldTaskToRemove != null)
        {
            DestroyImmediate(oldTaskToRemove, true);
        }

        AssetDatabase.AddObjectToAsset(node.task, behaviourTreeAssetFilesPath);
        AssetDatabase.ImportAsset(behaviourTreeAssetFilesPath);
        AssetDatabase.Refresh();
    }
Пример #2
0
        // Draw the property inside the given rect
        public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
        {
            EditorGUI.BeginProperty(position, label, property);
            object variable = property.serializedObject.targetObject;

            EditorSharedVariable sharedVariable = Base.Common.EditorHelpers.GetTargetObjectOfProperty(property) as EditorSharedVariable;
            BehaviourTreeTask    objectVariable = variable as BehaviourTreeTask;

            // Draw label
            position = EditorGUI.PrefixLabel(position, GUIUtility.GetControlID(FocusType.Passive), label);

            // Don't make child fields be indented
            var indent = EditorGUI.indentLevel;

            EditorGUI.indentLevel = 0;

            if (objectVariable.treeOwner == null)
            {
                return;
            }

            string[] possibleNames = objectVariable.treeOwner.Blackboard.getNamesOfVariablesByType(sharedVariable.type);
            selectedIndex = 0;
            for (int a = 0; a < possibleNames.Length; ++a)
            {
                if (possibleNames[a] == sharedVariable.name)
                {
                    selectedIndex = a;
                    break;
                }
            }

            // Calculate rect
            var nameRect = new Rect(position.x, position.y, 150, position.height);
            //choose from possible list
            int newIndex = EditorGUI.Popup(nameRect, selectedIndex, possibleNames);

            if (possibleNames.Length > 0)
            {
                sharedVariable.name = possibleNames[newIndex];
                selectedIndex       = newIndex;
            }


            // Set indent back to what it was
            EditorGUI.indentLevel = indent;

            EditorGUI.EndProperty();
        }
Пример #3
0
        private void DrawConnections(BehaviourTreeTask node)
        {
            Vector2 startPosition = new Vector2(node.NodeRect.center.x, node.NodeRect.yMax - 10);

            if (!selectedBehaviour.hasAnyChildren(node))
            {
                return;
            }
            foreach (BehaviourTreeTask child in selectedBehaviour.getAllChildren(node))
            {
                Vector2 endPosition = new Vector2(child.NodeRect.center.x, child.NodeRect.yMin + 10);
                Vector2 distance    = endPosition - startPosition;
                distance.x  = 0;
                distance.y *= 0.8f;
                Handles.DrawBezier(startPosition, endPosition, startPosition + distance, endPosition - distance, Color.white, null, 3.0f);
            }
        }
Пример #4
0
        private Vector2 computeStartPositionFor(BehaviourTreeTask forTask)
        {
            Rect    startRect = forTask.NodeRect;
            Vector2 pos       = startRect.position;
            //check children and put it at the most right position
            BehaviourTreeTask lastChild = forTask.getLastChildPos();

            if (lastChild == null)
            {
                pos.y += startRect.height * 2;
            }
            else
            {
                pos    = lastChild.NodeRect.position;
                pos.x += startRect.width * 2;
            }
            return(pos);
        }
Пример #5
0
        private BehaviourTreeTask getNodeAt(Vector2 pos)
        {
            BehaviourTreeTask selectedNode = null;

            pos += scrollPosition;
            pos /= scaling;
            foreach (BehaviourTreeTask current in selectedBehaviour.GetNodes())
            {
                Rect local = current.NodeRect;
                //local.width *= scaling;
                // local.height *= scaling;
                if (local.Contains(pos))
                {
                    selectedNode = current;
                }
            }
            return(selectedNode);
        }
Пример #6
0
        private void OnGUI()
        {
            if (selectedBehaviour == null)
            {
                EditorGUILayout.LabelField("No behaviour tree selected");
            }
            else
            {
                processEvents();

                GUILayout.BeginVertical();

                drawTopPanel();

                GUILayout.BeginHorizontal();

                drawLeftPanel();

                // drawTreeArea();
                DrawScrollView();

                GUILayout.EndHorizontal();

                GUILayout.EndVertical();

                if (addNodeFor != null)
                {
                    //add empty child node for selected node
                    selectedBehaviour.createNode(addNodeFor, Event.current.mousePosition);
                    addNodeFor = null;
                }

                if (nodeToRemove != null)
                {
                    //remove selected node and all his connections
                    Undo.RegisterCompleteObjectUndo(selectedBehaviour, "Remove objects");
                    selectedBehaviour.removeNode(nodeToRemove);
                    EditorUtility.SetDirty(selectedBehaviour);
                    nodeToRemove = null;
                }
            }
        }
 public BehaviourTreeDecorator(BehaviourTreeTask Task)
 {
     this.Task = Task;
 }
 public BehaviourTreeDecoratorInverter(BehaviourTreeTask task) : base(task)
 {
 }
 public BehaviourTreeDecoratorFilter(Func <bool> Condition, BehaviourTreeTask task) : base(task)
 {
     this.Condition = Condition;
 }
 public BehaviourTreeDecoratorUntilFail(BehaviourTreeTask task) : base(task)
 {
 }
 public BehaviourTreeDecoratorLimit(int maxRepetition, BehaviourTreeTask task) : base(task)
 {
     this.maxRepetition = maxRepetition;
     count = 0;
 }
Пример #12
0
        ///////////////////////////////////////////////////////
        #endregion

        private void processEvents()
        {
            Event currentEvent = Event.current;

            if (currentEvent.type == EventType.MouseDown && currentNode == null)
            {
                //Debug.Log("mouse pos scaled:  " + mousePosition + " mouse position normal: " + currentEvent.mousePosition+" scaling: "+scaling);
                currentNode = getNodeAt(currentEvent.mousePosition - new Vector2(leftPanelSize.x, topPanelHeight));
                if (currentNode != null)
                {
                    localOffsetForDrag     = currentEvent.mousePosition;
                    Selection.activeObject = currentNode;

                    //set as selectd node
                    selectedNode = currentNode;
                    ActionTreeTask actionTask = selectedNode as ActionTreeTask;
                    if (actionTask != null)
                    {
                        //create serialized object for editor modification
                        selectedSerializedAction = new SerializedObject(selectedNode);
                        selectedSerializedAction.Update();
                    }

                    GUI.changed = true;
                }
                else
                {
                    if (currentEvent.mousePosition.x > leftPanelSize.x && currentEvent.mousePosition.x < this.position.width - GUI.skin.verticalScrollbar.fixedWidth * 2.5f &&
                        currentEvent.mousePosition.y < this.position.height - 20.0f)
                    {
                        draggingCanvas         = true;
                        draggingOffset         = currentEvent.mousePosition + scrollPosition;
                        Selection.activeObject = selectedBehaviour;
                    }
                }
            }
            else if (currentEvent.type == EventType.MouseDrag && currentNode != null)
            {
                Undo.RecordObject(selectedBehaviour, "Drag panel");
                Rect    oldRect = currentNode.NodeRect;
                Vector2 offset  = (currentEvent.mousePosition - localOffsetForDrag) / scaling;
                localOffsetForDrag   = currentEvent.mousePosition;
                oldRect.position    += offset;
                oldRect.position     = new Vector2(Mathf.Clamp(oldRect.position.x, 0, 10000), Mathf.Clamp(oldRect.position.y, 0, 10000));
                currentNode.NodeRect = oldRect;
                GUI.changed          = true;
            }
            else if (currentEvent.type == EventType.MouseDrag && draggingCanvas)
            {
                Undo.RecordObject(selectedBehaviour, "Drag view");
                scrollPosition = draggingOffset - currentEvent.mousePosition;
                GUI.changed    = true;
            }
            else if (currentEvent.type == EventType.MouseUp && currentNode != null)
            {
                currentNode = null;
            }
            else if (currentEvent.type == EventType.MouseUp && draggingCanvas)
            {
                draggingCanvas = false;
            }
        }
Пример #13
0
        private void onDrawTasksPanel()
        {
            if (selectedNode == null)
            {
                GUILayout.Label("No selected node");
            }
            else if (selectedNode.taskType == TaskType.ACTION)
            {
                GUILayout.Label("Selected node is a leaf node");
            }
            else if (selectedNode.taskType == TaskType.DECORATOR && selectedNode.children.Count > 0 &&
                     ((DecoratorTreeTask)selectedNode).OnlySingleChildAllowed)
            {
                GUILayout.Label("Selected node has OnlyOneChildAllowed flag enabled, cannot add new childen");
            }
            else
            {
                GUILayout.BeginVertical();

                GUILayout.Space(20);
                GUILayout.Label("__________________COMPOSITES__________________");
                GUILayout.Space(20);
                foreach (BehaviourTreeTask current in behaviourTasks_Composite)
                {
                    // Debug.Log(current.name);
                    if (GUILayout.Button(current.taskTypeName))
                    {
                        Type    toCreate = current.GetType();
                        Vector2 createAt = computeStartPositionFor(selectedNode);
                        var     element  = selectedBehaviour.createNodeOfType(toCreate, selectedNode, createAt);
                        if (element != null)
                        {
                            selectedNode = element;
                            selectedNode.editorTexture = current.editorTexture;
                            selectedNode.taskTypeName  = current.taskTypeName;
                            selectedNode.taskType      = current.taskType;
                        }
                    }
                }
                GUILayout.Space(20);
                GUILayout.Label("__________________DECORATORS__________________");
                GUILayout.Space(20);
                foreach (BehaviourTreeTask current in behaviourTasks_Decorators)
                {
                    // Debug.Log(current.name);
                    if (GUILayout.Button(current.taskTypeName))
                    {
                        Type    toCreate = current.GetType();
                        Vector2 createAt = computeStartPositionFor(selectedNode);
                        var     element  = selectedBehaviour.createNodeOfType(toCreate, selectedNode, createAt);
                        if (element != null)
                        {
                            selectedNode = element;
                            selectedNode.editorTexture = current.editorTexture;
                            selectedNode.taskTypeName  = current.taskTypeName;
                            selectedNode.taskType      = current.taskType;
                        }
                    }
                }
                GUILayout.Space(20);
                GUILayout.Label("__________________ACTIONS__________________");
                GUILayout.Space(20);
                foreach (BehaviourTreeTask current in behaviourTasks_Actions)
                {
                    // Debug.Log(current.name);
                    if (GUILayout.Button(current.taskTypeName))
                    {
                        Type    toCreate = current.GetType();
                        Vector2 createAt = computeStartPositionFor(selectedNode);
                        var     element  = selectedBehaviour.createNodeOfType(toCreate, selectedNode, createAt);
                        selectedNode = element;
                        selectedNode.editorTexture = current.editorTexture;
                        selectedNode.taskTypeName  = current.taskTypeName;
                        selectedNode.taskType      = current.taskType;
                    }
                }

                GUILayout.EndVertical();
            }
        }
Пример #14
0
        /// <summary>
        /// DRAW UI
        /// </summary>
        private void DrawNode(BehaviourTreeTask node)
        {
            Color lastColor = GUI.backgroundColor;

            if (selectedNode == node)
            {
                GUI.backgroundColor = Color.green;
            }
            else
            {
                GUI.backgroundColor = lastColor;
            }
            if (node.taskType != TaskType.ROOT)
            {
                Rect upperPartRect = new Rect(node.NodeRect.x + node.NodeRect.width * 0.5f - node.NodeRect.width * 0.3f, node.NodeRect.y - node.NodeRect.height * 0.1f,
                                              node.NodeRect.width * 0.6f, node.NodeRect.height * 0.3f);
                GUILayout.BeginArea(upperPartRect, nodeStyle);

                GUILayout.EndArea();
            }

            if (node.taskType != TaskType.ACTION)
            {
                Rect lowerPartRect = new Rect(node.NodeRect.x + node.NodeRect.width * 0.5f - node.NodeRect.width * 0.3f, node.NodeRect.y + node.NodeRect.height * 0.8f,
                                              node.NodeRect.width * 0.6f, node.NodeRect.height * 0.3f);
                GUILayout.BeginArea(lowerPartRect, nodeStyle);

                GUILayout.EndArea();
            }

            GUILayout.BeginArea(node.NodeRect, nodeStyle);
            GUI.skin.label.alignment = TextAnchor.MiddleCenter;
            GUI.skin.box.alignment   = TextAnchor.MiddleCenter;
            GUILayout.BeginVertical();

            GUILayout.Label(node.taskTypeName);

            GUILayout.BeginHorizontal();
            GUILayout.FlexibleSpace();
            GUILayout.Box(node.editorTexture);
            GUILayout.FlexibleSpace();
            GUILayout.EndHorizontal();


            GUILayout.EndVertical();


            GUILayout.EndArea();

            if (node.taskType != TaskType.ROOT)
            {
                Rect nodeRectFull = node.NodeRect;
                Rect buttonRect   = new Rect(nodeRectFull.x - 10.0f + nodeRectFull.width * 0.5f, nodeRectFull.y + nodeRectFull.height * 0.7f, 20.0f, 20.0f);
                //buttons for erasing
                if (GUI.Button(buttonRect, "x"))
                {
                    //delete node
                    if (!reparenting)
                    {
                        nodeToRemove = node;
                    }
                }
                //draw option for reparenting
                Rect reparentRect = new Rect(nodeRectFull.x - 10.0f + nodeRectFull.width * 0.8f, nodeRectFull.y + nodeRectFull.height * 0.7f, 20.0f, 20.0f);
                if (reparenting)
                {
                    if (selectedForReparenting == node)
                    {
                        var oldColor = GUI.backgroundColor;
                        GUI.backgroundColor = Color.red;
                        if (GUI.Button(reparentRect, "R"))
                        {
                            reparenting            = false;
                            selectedForReparenting = null;
                        }
                        GUI.backgroundColor = oldColor;
                    }
                    else
                    {
                        var oldColor = GUI.backgroundColor;
                        GUI.backgroundColor = Color.green;
                        if (GUI.Button(reparentRect, "R"))
                        {
                            BehaviourTree.Reparent(node, selectedForReparenting);
                            reparenting            = false;
                            selectedForReparenting = null;
                        }
                        GUI.backgroundColor = oldColor;
                    }
                }
                else
                {
                    if (GUI.Button(reparentRect, "R"))
                    {
                        reparenting            = true;
                        selectedForReparenting = node;
                    }
                }
            }

            GUI.backgroundColor = lastColor;
        }
Пример #15
0
 public BehaviourTree(BehaviourTreeTask root)
 {
     this.root = root;
 }
Пример #16
0
    void ExecutionWindowFunction(int windowID)
    {
        BehaviourTreeExecutionNode node = (BehaviourTreeExecutionNode)FindNodeByID(BehaviourTreeEditorWindow.behaviourTree, windowID);

        Event current = Event.current;

        if (current.mousePosition.x >= 0.0f && current.mousePosition.x <= nodeSize.x * zoomScale &&
            current.mousePosition.y >= 0.0f && current.mousePosition.y <= nodeSize.y * zoomScale &&
            DragAndDrop.objectReferences.Length == 1)
        {
            Object taskScriptAsset = DragAndDrop.objectReferences[0];

            if (!(taskScriptAsset is MonoScript))
            {
                DragAndDrop.visualMode = DragAndDropVisualMode.Rejected;
            }
            else
            {
                DragAndDrop.visualMode = DragAndDropVisualMode.Link;
            }
        }

        if (current.type == EventType.MouseDown && current.button == 1)
        {
            this.selectedNode = node;

            if (Selection.activeObject != BehaviourTreeEditorWindow.behaviourTree)
            {
                SelectNodeButDontChangeProjectView();
            }

            GenericMenu menu = new GenericMenu();

            AddInsertNewParentOptions(menu);
            AddMoveOption(menu);
            menu.AddItem(new GUIContent("Delete Node"), false, DeleteNodeCallback);
            menu.ShowAsContext();

            current.Use();
        }
        else if (current.type.Equals(EventType.DragExited))
        {
            Object taskScriptAsset = DragAndDrop.objectReferences[0];

            if (!(taskScriptAsset is MonoScript))
            {
                current.Use();
                return;
            }

            System.Type taskType = (taskScriptAsset as MonoScript).GetClass();

            ScriptableObject so = ScriptableObject.CreateInstance(taskType);

            if (!(so is BehaviourTreeTask))
            {
                current.Use();
                return;
            }

            BehaviourTreeTask oldTaskToRemove = node.task;

            node.task = so as BehaviourTreeTask;

            node.contextLink.Clear();

            PropertyReader.Variable[] variables = PropertyReader.GetFields(node.task.GetType());

            foreach (PropertyReader.Variable variable in variables)
            {
                if (variable.name.StartsWith("in_") || variable.name.StartsWith("out_"))
                {
                    node.contextLink.Add(variable.name, variable.name.Split('_')[1]);
                }
            }

            node.displayedName = taskType.ToString();

            AddTaskToAssets(node, oldTaskToRemove);

            BehaviourTreeEditorWindow.SaveBehaviourTree();

            this.selectedNode = node;

            Selection.activeObject = taskScriptAsset;

            SelectNodeButDontChangeProjectView();

            current.Use();
        }
        else if (current.type == EventType.MouseDown && current.button == 0 && current.clickCount == 2)
        {
            this.selectedNode = node;

            if (Selection.activeObject != BehaviourTreeEditorWindow.behaviourTree)
            {
                SelectNodeButDontChangeProjectView();
            }

            MonoScript monoscript = MonoScript.FromScriptableObject(node.task);
            string     scriptPath = AssetDatabase.GetAssetPath(monoscript);
            UnityEditorInternal.InternalEditorUtility.OpenFileAtLineExternal(scriptPath, 0);

            current.Use();
        }
        else if (current.type == EventType.MouseDown && current.button == 0)
        {
            this.selectedNode = node;

            if (Selection.activeObject != BehaviourTreeEditorWindow.behaviourTree)
            {
                SelectNodeButDontChangeProjectView();
            }

            current.Use();
        }
    }