예제 #1
0
    public void Update()
    {
        if (current == AgentState.IDLE)
        {
            //Transizione a PLANNING: se l'agente ha un task obiettivo non completato, o non esiste una condizione obiettivo, ma il manager delle azioni è comunque in stato STOP

            if (agent.goal.methods.Count > 0 && !agent.goal.completed && (Time.frameCount % 60 == 0 || Time.frameCount == 1))
            {
                current = AgentState.PLANNING;
            }

            //Transizione a EXECUTING: se il manager delle azioni è in stato EXECUTE
            else if (agent.actionManager.state == ManagerState.EXECUTE)
            {
                current = AgentState.EXECUTING;
            }

            else if (agent.actionManager.state == ManagerState.PAUSE)
            {
                PrimitiveTask currentTask = (PrimitiveTask)agent.actionManager.currentAction;

                foreach (CuncurrentTask cuncurrent in currentTask.cuncurrentTasks)
                {
                    if (!currentTask.CheckCuncurrency(cuncurrent, agent))
                    {
                        return;
                    }
                }

                agent.actionManager.Resume();
            }
        }
        else if (current == AgentState.PLANNING)
        {
            /*In this state, agent plans to goal
             * Transition to EXECUTING : if agent has a plan towards goal (not empty actions list)
             * Transizion to IDLE: agent has no plan towards goal (empty actions list)*/


            //Generate or fix plan
            List <Task> tasks = new List <Task>();

            //If manager has stopped with INVALID state, fix plan and get a new plan
            if (agent.actionManager.state == ManagerState.INVALID)
            {
                //Climb the hierarchy and get the first valid node
                CompoundTask validNode = Planner.GetValidNode((PrimitiveTask)agent.actionManager.currentAction, agent.state);

                tasks.Add(validNode);


                //Generate first segment of fixed plan, planning from the node found

                List <PrimitiveTask> firstSegment = Planner.GeneratePlan(tasks, agent);

                if (firstSegment.Count > 0)
                {
                    //Get second segment from the current plan, deleting tasks who have node found as father or forefather
                    List <PrimitiveTask> secondSegment = new List <PrimitiveTask>();

                    foreach (PrimitiveTask task in agent.plan)
                    {
                        if (!task.IsMyForeFather(validNode) && !task.completed)
                        {
                            secondSegment.Add(task);
                        }
                    }

                    //Fix the plan concatenating first segment with second segment
                    agent.plan = firstSegment.Concat(secondSegment).ToList <PrimitiveTask>();
                }

                //No plan..
                else
                {
                    agent.plan = new List <PrimitiveTask>();

                    //If agent is a member of a group, notify it to the leader, who will stop execution of global plan
                    agent.communicationSystem.sendMessage(new Message(agent.leader, MessageContent.ORDER_FAILURE));
                }
            }

            //Otherwise generate plan
            else
            {
                tasks.Add(agent.goal);

                agent.plan = Planner.GeneratePlan(tasks, agent);
            }


            if (agent.plan != null)
            {
                foreach (IGroundAction action in agent.plan)
                {
                    agent.actionManager.ScheduleAction(action);
                }

                agent.actionManager.NextAction();

                current = AgentState.EXECUTING;

                agent.actionManager.state = ManagerState.EXECUTE;
            }
            else
            {
                agent.actionManager.state = ManagerState.STOP;

                current = AgentState.IDLE;
            }
        }
        else if (current == AgentState.EXECUTING)
        {
            //Dentro lo stato: esecuzione azione corrente del piano
            //Transizione a IDLE : se il piano è completato con successo, oppure il manager delle azioni è andato in pausa
            //Transizione a PLANNING : se il piano non è valido (precondizioni azione non valide)

            agent.actionManager.RunCurrentAction();

            if (agent.actionManager.state == ManagerState.EMPTY)
            {
                current = AgentState.IDLE;

                agent.actionManager.state = ManagerState.STOP;

                agent.goal.completed = true;
            }
            else if (agent.actionManager.state == ManagerState.INVALID)
            {
                current = AgentState.PLANNING;
            }

            else if (agent.actionManager.state == ManagerState.PAUSE)
            {
                current = AgentState.IDLE;
            }
        }
    }
예제 #2
0
    public void InstantiateVariables(Task task, List <Term> variables)
    {
        if (task.GetType() == typeof(PrimitiveTask))
        {
            PrimitiveTask pt = (PrimitiveTask)task;

            foreach (Term variable in variables)
            {
                int index = pt.arguments.FindIndex((Term arg) => arg.key == variable.key);

                if (index >= 0)
                {
                    pt.arguments[index] = variable;
                }

                foreach (Atom pre in pt.preconditions)
                {
                    index = pre.terms.FindIndex((Term arg) => arg.key == variable.key);

                    if (index >= 0)
                    {
                        pre.terms[index] = variable;
                    }
                }


                foreach (Atom eff in pt.effects)
                {
                    index = eff.terms.FindIndex((Term arg) => arg.key == variable.key);

                    if (index >= 0)
                    {
                        eff.terms[index] = variable;
                    }
                }
            }
        }
        else if (task.GetType() == typeof(CompoundTask))
        {
            CompoundTask ct = (CompoundTask)task;

            foreach (Method m in ct.methods)
            {
                foreach (Atom pre in m.preconditions)
                {
                    foreach (Term variable in variables)
                    {
                        int index = pre.terms.FindIndex((Term arg) => arg.key == variable.key);

                        if (index >= 0)
                        {
                            pre.terms[index] = variable;
                        }
                    }
                }


                foreach (Task subTask in m.subtasks)
                {
                    InstantiateVariables(subTask, variables);
                }
            }
        }
    }
예제 #3
0
    static List <PrimitiveTask> SHOPNoBack(List <Task> tasks, List <PrimitiveTask> plan, string personality, State state, HTNAgent agent)
    {
        Task task = tasks [0];

        if (task.GetType() == typeof(PrimitiveTask))
        {
            PrimitiveTask pt = (PrimitiveTask)task;


            PrimitiveTask groundAction = InstantiateAction(pt, state, agent);

            if (groundAction != null)
            {
                plan.Add(groundAction);

                tasks.Remove(pt);

                if (tasks.Count > 0)
                {
                    return(SHOPNoBack(tasks, plan, personality, pt.apply(state), agent));
                }
            }
            else
            {
                return(null);
            }
        }
        else if (task.GetType() == typeof(CompoundTask))
        {
            CompoundTask ct = (CompoundTask)task;


            List <Method> orderdedMethods = new List <Method>();

            switch (agent.methodsOrdering)
            {
            case MethodsOrdering.NONE:
                orderdedMethods = ct.methods;
                break;

            case MethodsOrdering.PREF:
                orderdedMethods = ct.methods.OrderBy(m => m.preference != personality).ToList();
                break;

            case MethodsOrdering.COSTANDPREF:
                orderdedMethods = ct.methods.OrderBy(m => m.leastCost()).ThenBy(m => m.preference != personality).ToList();
                break;
            }


            foreach (Method m in orderdedMethods)
            {
                if (RuleMatcher.MatchCondition(m.preconditions, state, m.logicalOperator))
                {
                    List <Task> tempTasks = new List <Task>(tasks);

                    tempTasks.Remove(task);

                    int j = 0;

                    foreach (Task subtask in m.subtasks)
                    {
                        tempTasks.Insert(0 + j, subtask);
                        j++;
                    }
                    List <PrimitiveTask> tempPlan = SHOPNoBack(tempTasks, plan, personality, state, agent);


                    if (tempPlan != null)
                    {
                        plan.Concat(tempPlan);
                        break;
                    }
                    else
                    {
                        return(null);
                    }
                }
            }
        }

        return(plan);
    }
예제 #4
0
    public void plan(GameController.WorldState currentWorldState)
    {
        finalPlan = new Stack <PrimitiveTask>();
        Stack <PlannerState> decompHistory = new Stack <PlannerState>();

        GameController.WorldState WorkingWS = currentWorldState.Copy();

        tasksToProcess.Push(new PlayGame());

        while (tasksToProcess.Count > 0)
        {
            Task CurrentTask = tasksToProcess.Pop();
            if (CurrentTask.GetType().IsSubclassOf(typeof(CompoundTask)))
            {
                CompoundTask CurrentCompoundTask = (CompoundTask)CurrentTask;
                Method       SatisfiedMethod     = CurrentCompoundTask.FindSatisfiedMethod(WorkingWS);

                if (SatisfiedMethod != null)
                {
                    //PlannerState currentState = new PlannerState(CurrentCompoundTask, finalPlan, tasksToProcess, SatisfiedMethod);
                    // decompHistory.Push(currentState);
                    SatisfiedMethod.subTasks.Reverse();
                    foreach (Task t in SatisfiedMethod.subTasks)
                    {
                        tasksToProcess.Push(t);
                    }
                    SatisfiedMethod.subTasks.Reverse();
                }
                else if (decompHistory.Count > 0)
                {
                    //RestoreToLastDecomposedTask():
                    PlannerState lastState        = decompHistory.Pop();
                    CompoundTask lastCompoundTask = lastState.currentTask;
                    finalPlan      = lastState.finalPlan;
                    tasksToProcess = lastState.tasksToProcess;
                    // Remove the failed method and return CompoundTask to the stack. On the next iteration, it will be checked again for a valid method.
                    lastCompoundTask.InvalidateMethod(lastState.currentMethod);
                    tasksToProcess.Push(lastCompoundTask);
                }
            }
            else//Primitive Task
            {
                PrimitiveTask CurrentPrimitiveTask = (PrimitiveTask)CurrentTask;
                if (CurrentPrimitiveTask.PrimitiveConditionsMet(WorkingWS))
                {
                    // CurrentPrimitiveTask.ApplyEffects(this, WorkingWS);
                    // Add this PrimitiveTask to the bottom of the finalPlan
                    Stack <PrimitiveTask> temp = new Stack <PrimitiveTask>();
                    for (int i = 0; i < finalPlan.Count; i++)
                    {
                        PrimitiveTask nextTask = finalPlan.Pop();
                        temp.Push(nextTask);
                    }
                    temp.Push(CurrentPrimitiveTask);
                    finalPlan = new Stack <PrimitiveTask>();
                    for (int i = 0; i < temp.Count; i++)
                    {
                        PrimitiveTask nextTask = temp.Pop();
                        finalPlan.Push(nextTask);
                    }
                }
                else if (decompHistory.Count > 0)
                {
                    //RestoreToLastDecomposedTask();
                    PlannerState lastState        = decompHistory.Pop();
                    CompoundTask lastCompoundTask = lastState.currentTask;
                    finalPlan      = lastState.finalPlan;
                    tasksToProcess = lastState.tasksToProcess;
                    // Remove the failed method and return CompoundTask to the stack. On the next iteration, it will be checked again for a valid method.
                    lastCompoundTask.InvalidateMethod(lastState.currentMethod);
                    tasksToProcess.Push(lastCompoundTask);
                }
            }
        }
    }
예제 #5
0
    void OnGUI()
    {
        //A line separates HTN Editor from task editor
        Drawing.DrawLine(new Vector2(302, 0), new Vector2(302, 700), Color.grey, 2.0f, false);



        /*HTN EDITOR*/
        items = new List <HTNEditorItem>();

        items.Add(new HTNEditorItem(
                      new Rect(new Vector2(0, 0), new Vector2(100, 30)),
                      goal, itemType.COMPOUND));


        DrawCompoundTask(goal, null, new Vector2(10, 0));

        //GUI.EndScrollView ();
        Event currentEvent = Event.current;

        foreach (HTNEditorItem htnItem in items)
        {
            if (currentEvent.type == EventType.MouseDown &&
                currentEvent.button == 0 &&
                htnItem.area.Contains(currentEvent.mousePosition)
                )
            {
                selected = htnItem;
            }
        }



        /*TASK EDITOR*/

        if (selected.item != null)
        {
            GUIStyle labelStyle = new GUIStyle();

            labelStyle.fontSize         = 12;
            labelStyle.normal.textColor = Color.black;
            labelStyle.fontStyle        = FontStyle.Bold;



            if (selected.type == itemType.COMPOUND)
            {
                int i = 0;


                CompoundTask selectedCT = (CompoundTask)selected.item;



                GUI.Label(new Rect(editorPos, itemSize), "Name", labelStyle);

                selectedCT.name = GUI.TextField(new Rect(new Vector2(editorPos.x + 50, editorPos.y),
                                                         new Vector2(75, 20)),
                                                selectedCT.name);

                if (selectedCT.Equals(goal))
                {
                    GUI.Label(new Rect(new Vector2(editorPos.x, editorPos.y + 100), itemSize), "Goal condition", labelStyle);


                    GUI.Label(new Rect(new Vector2(editorPos.x, editorPos.y + 125), new Vector2(120, 20)), "Logical operator");

                    string[] operatorOptions = new string[] { "AND", "OR" };

                    int selectedOperator = Array.IndexOf <string> (operatorOptions, agent.logicalOperator.ToString());

                    selectedOperator = EditorGUI.Popup(new Rect(new Vector2(editorPos.x + 100, editorPos.y + 125), new Vector2(50, 20)),
                                                       selectedOperator, operatorOptions);
                    if (selectedOperator == 0)
                    {
                        agent.logicalOperator = LogicalOperator.AND;
                    }
                    else if (selectedOperator == 1)
                    {
                        agent.logicalOperator = LogicalOperator.OR;
                    }



                    if (agent.goalCondition.Count > 0)
                    {
                        for (i = 0; i < agent.goalCondition.Count; i++)
                        {
                            Atom cond = agent.goalCondition[i];


                            string condLabelName = string.Concat(cond.name, "(");

                            foreach (Term var in cond.terms)
                            {
                                condLabelName = string.Concat(condLabelName, var.key);

                                if (cond.terms.IndexOf(var) < cond.terms.Count - 1)
                                {
                                    condLabelName = string.Concat(condLabelName, ",");
                                }
                            }

                            condLabelName = string.Concat(condLabelName, ")");


                            GUI.Label(new Rect(
                                          new Vector2(editorPos.x, editorPos.y + 150 + i * 25), new Vector2(200, 50)), condLabelName);



                            if (GUI.Button(new Rect(new Vector2(editorPos.x + 110, editorPos.y + 150 + i * 25),
                                                    new Vector2(50, 15)), "Edit"))
                            {
                                ConditionEditorWindow.ShowWindow(agent, cond);
                            }

                            if (GUI.Button(new Rect(new Vector2(editorPos.x + 175, editorPos.y + 150 + i * 25),
                                                    new Vector2(50, 15)), "Delete"))
                            {
                                agent.goalCondition.Remove(cond);
                                ConditionEditorWindow.GetWindow <ConditionEditorWindow>().Close();
                            }
                        }
                    }



                    if (GUI.Button(new Rect(new Vector2(editorPos.x, editorPos.y + 150 + i * 25),
                                            new Vector2(75, 20)),
                                   "Add "))
                    {
                        Atom cond = new Atom("New Condition");

                        agent.goalCondition.Add(cond);

                        ConditionEditorWindow.ShowWindow(agent, cond);
                    }
                }
            }



            else if (selected.type == itemType.PRIMITIVE)
            {
                PrimitiveTask selectedPT = (PrimitiveTask)selected.item;



                GUI.Label(new Rect(editorPos, itemSize), "Name", labelStyle);

                selectedPT.name = GUI.TextField(new Rect(new Vector2(editorPos.x + 50, editorPos.y), new Vector2(75, 20)),
                                                selectedPT.name);



                GUI.Label(new Rect(new Vector2(editorPos.x, editorPos.y + 50), itemSize), "Cost", labelStyle);

                selectedPT.cost = EditorGUI.FloatField(new Rect(new Vector2(editorPos.x + 50, editorPos.y + 50),
                                                                new Vector2(75, 20)),
                                                       selectedPT.cost);



                GUI.Label(new Rect(new Vector2(editorPos.x, editorPos.y + 90), itemSize), "Arguments", labelStyle);

                int i = 0;


                scrollPositionArg = GUI.BeginScrollView(new Rect(new Vector2(editorPos.x, editorPos.y + 120), new Vector2(300, 50)),
                                                        scrollPositionArg, new Rect(new Vector2(editorPos.x, editorPos.y + 120),
                                                                                    new Vector2(275, 50 + selectedPT.arguments.Count * 10)), false, false);


                if (selectedPT.arguments.Count > 0)
                {
                    for (i = 0; i < selectedPT.arguments.Count; i++)
                    {
                        //GUILayout.BeginHorizontal(GUILayout.Width(200));
                        GUI.Label(new Rect(
                                      new Vector2(editorPos.x, editorPos.y + 120 + i * 25), itemSize), "Name");



                        List <string> domVarNamesList = new List <string> ();


                        foreach (Term v in agent.domainVariables)
                        {
                            domVarNamesList.Add(v.key);
                        }

                        varIndex = domVarNamesList.IndexOf(selectedPT.arguments[i].key);

                        if (varIndex == -1)
                        {
                            varIndex = 0;
                        }

                        varIndex = EditorGUI.Popup(new Rect(new Vector2(editorPos.x + 105, editorPos.y + 120 + i * 25),
                                                            new Vector2(50, 20)), varIndex, domVarNamesList.ToArray());


                        selectedPT.arguments[i] = agent.domainVariables[varIndex];


                        if (GUI.Button(new Rect(new Vector2(editorPos.x + 160, editorPos.y + 120 + i * 25),
                                                new Vector2(50, 15)), "Delete"))
                        {
                            selectedPT.deleteArgument(selectedPT.arguments[i]);
                        }
                    }
                }

                GUI.EndScrollView();



                Vector2 AddButtonPos = new Vector2(0, 0);

                if (selectedPT.arguments.Count == 0)
                {
                    AddButtonPos = new Vector2(editorPos.x, editorPos.y + 120);
                }

                else if (selectedPT.arguments.Count > 0)
                {
                    AddButtonPos = new Vector2(editorPos.x, editorPos.y + 170);
                }


                if (GUI.Button(new Rect(AddButtonPos, new Vector2(75, 20)), "Add"))
                {
                    foreach (Term argument in agent.domainVariables)
                    {
                        if (!selectedPT.arguments.Contains(argument))
                        {
                            selectedPT.addArgument(argument);
                            break;
                        }
                    }
                }



                i = 0;

                GUI.Label(new Rect(new Vector2(editorPos.x, editorPos.y + 210 + i * 25), new Vector2(120, 20)), "Preconditions", labelStyle);


                GUI.Label(new Rect(new Vector2(editorPos.x, editorPos.y + 240), new Vector2(120, 20)), "Logical operator");


                string[] operatorOptions = new string[] { "AND", "OR" };

                int selectedOperator = Array.IndexOf <string> (operatorOptions, selectedPT.logicalOperator.ToString());

                selectedOperator = EditorGUI.Popup(new Rect(new Vector2(editorPos.x + 100, editorPos.y + 240), new Vector2(50, 20)),
                                                   selectedOperator, operatorOptions);
                if (selectedOperator == 0)
                {
                    selectedPT.logicalOperator = LogicalOperator.AND;
                }
                else if (selectedOperator == 1)
                {
                    selectedPT.logicalOperator = LogicalOperator.OR;
                }



                scrollPositionPre = GUI.BeginScrollView(new Rect(new Vector2(editorPos.x, editorPos.y + 265), new Vector2(300, 50)),
                                                        scrollPositionPre, new Rect(new Vector2(editorPos.x, editorPos.y + 265),
                                                                                    new Vector2(275, 50 + selectedPT.preconditions.Count * 10)), false, false);

                if (selectedPT.preconditions.Count > 0)
                {
                    for (i = 0; i < selectedPT.preconditions.Count; i++)
                    {
                        Atom pre = selectedPT.preconditions[i];


                        string preLabelName = "";

                        if (pre.sign == false)
                        {
                            preLabelName = string.Concat("NOT(", pre.name, "(");
                        }
                        else if (pre.sign == true)
                        {
                            preLabelName = string.Concat(pre.name, "(");
                        }

                        foreach (Term var in pre.terms)
                        {
                            preLabelName = string.Concat(preLabelName, var.key);

                            if (pre.terms.IndexOf(var) < pre.terms.Count - 1)
                            {
                                preLabelName = string.Concat(preLabelName, ",");
                            }
                        }

                        if (pre.sign == true)
                        {
                            preLabelName = string.Concat(preLabelName, ")");
                        }
                        else if (pre.sign == false)
                        {
                            preLabelName = string.Concat(preLabelName, "))");
                        }


                        GUI.Label(new Rect(
                                      new Vector2(editorPos.x, editorPos.y + 265 + i * 25), new Vector2(200, 50)), preLabelName);



                        if (GUI.Button(new Rect(new Vector2(editorPos.x + 110, editorPos.y + 265 + i * 25),
                                                new Vector2(50, 15)), "Edit"))
                        {
                            ConditionEditorWindow.ShowWindow(agent, pre);
                        }

                        if (GUI.Button(new Rect(new Vector2(editorPos.x + 175, editorPos.y + 265 + i * 25),
                                                new Vector2(50, 15)), "Delete"))
                        {
                            selectedPT.deletePrecondition(pre);

                            ConditionEditorWindow.GetWindow <ConditionEditorWindow>().Close();
                        }
                    }
                }


                GUI.EndScrollView();


                if (selectedPT.preconditions.Count == 0)
                {
                    AddButtonPos = new Vector2(editorPos.x, editorPos.y + 275);
                }

                else if (selectedPT.preconditions.Count > 0)
                {
                    AddButtonPos = new Vector2(editorPos.x, editorPos.y + 315);
                }


                if (GUI.Button(new Rect(AddButtonPos,
                                        new Vector2(75, 20)),
                               "Add "))
                {
                    Atom pre = new Atom("New Condition");

                    selectedPT.addPrecondition(pre);

                    ConditionEditorWindow.ShowWindow(agent, pre);
                }



                i = 0;

                GUI.Label(new Rect(new Vector2(editorPos.x, editorPos.y + 350 + i * 25), new Vector2(120, 20)), "Concurrent tasks", labelStyle);


                scrollPositionCunc = GUI.BeginScrollView(new Rect(new Vector2(editorPos.x, editorPos.y + 375), new Vector2(350, 75)),
                                                         scrollPositionCunc, new Rect(new Vector2(editorPos.x, editorPos.y + 375),
                                                                                      new Vector2(325, 75 + selectedPT.cuncurrentTasks.Count * 10)), false, false);

                for (i = 0; i < selectedPT.cuncurrentTasks.Count; i++)
                {
                    CuncurrentTask cuncurrent = selectedPT.cuncurrentTasks[i];


                    string[] options = new string[] { "True", "False" };

                    int selectedIndex = 0;

                    if (cuncurrent.sign == true)
                    {
                        selectedIndex = 0;
                    }

                    else if (cuncurrent.sign == false)
                    {
                        selectedIndex = 1;
                    }

                    selectedIndex = EditorGUI.Popup(new Rect(new Vector2(editorPos.x, editorPos.y + 375 + i * 25), new Vector2(75, 20)), selectedIndex, options);


                    if (selectedIndex == 0)
                    {
                        cuncurrent.sign = true;
                    }
                    else if (selectedIndex == 1)
                    {
                        cuncurrent.sign = false;
                    }

                    cuncurrent.task = GUI.TextField(new Rect(new Vector2(editorPos.x + 100, editorPos.y + 375 + i * 25), new Vector2(75, 20)), cuncurrent.task);

                    selectedPT.cuncurrentTasks[i] = cuncurrent;


                    int selectedVar = agent.domainVariables.IndexOf(agent.domainVariables.Find((Term t) => t.key == cuncurrent.agentVarName));

                    if (selectedVar == -1)
                    {
                        selectedVar = 0;
                    }

                    List <string> variablesNames = new List <string> ();

                    foreach (Term var in agent.domainVariables)
                    {
                        variablesNames.Add(var.key);
                    }


                    selectedVar = EditorGUI.Popup(new Rect(new Vector2(editorPos.x + 200, editorPos.y + 375 + i * 25), new Vector2(50, 20)),
                                                  selectedVar, variablesNames.ToArray());

                    cuncurrent.agentVarName = agent.domainVariables [selectedVar].key;


                    if (GUI.Button(new Rect(new Vector2(editorPos.x + 275, editorPos.y + 375 + i * 25), new Vector2(45, 15)), "Delete"))
                    {
                        selectedPT.cuncurrentTasks.Remove(selectedPT.cuncurrentTasks[i]);
                        ConditionEditorWindow.GetWindow <ConditionEditorWindow>().Close();
                    }
                }

                GUI.EndScrollView();


                if (selectedPT.cuncurrentTasks.Count == 0)
                {
                    AddButtonPos = new Vector2(editorPos.x, editorPos.y + 375);
                }

                else if (selectedPT.cuncurrentTasks.Count > 0)
                {
                    AddButtonPos = new Vector2(editorPos.x, editorPos.y + 425);
                }

                if (GUI.Button(new Rect(AddButtonPos, new Vector2(75, 20)), "Add"))
                {
                    selectedPT.cuncurrentTasks.Add(new CuncurrentTask(" ", false, agent.domainVariables[0].key));
                }



                i = 0;


                GUI.Label(new Rect(new Vector2(editorPos.x, editorPos.y + 475 + i * 25), new Vector2(120, 20)), "Effects", labelStyle);


                scrollPositionEff = GUI.BeginScrollView(new Rect(new Vector2(editorPos.x, editorPos.y + 500), new Vector2(300, 50)),
                                                        scrollPositionEff, new Rect(new Vector2(editorPos.x, editorPos.y + 475),
                                                                                    new Vector2(275, 50 + selectedPT.effects.Count * 10)), false, false);


                if (selectedPT.effects.Count > 0)
                {
                    for (i = 0; i < selectedPT.effects.Count; i++)
                    {
                        Atom eff = selectedPT.effects[i];



                        string effLabelName = "";

                        if (eff.sign == false)
                        {
                            effLabelName = string.Concat("NOT(", eff.name, "(");
                        }

                        else if (eff.sign == true)
                        {
                            effLabelName = string.Concat(eff.name, "(");
                        }

                        foreach (Term var in eff.terms)
                        {
                            effLabelName = string.Concat(effLabelName, var.key);

                            if (eff.terms.IndexOf(var) < eff.terms.Count - 1)
                            {
                                effLabelName = string.Concat(effLabelName, ",");
                            }
                        }


                        if (eff.sign == true)
                        {
                            effLabelName = string.Concat(effLabelName, ")");
                        }
                        else if (eff.sign == false)
                        {
                            effLabelName = string.Concat(effLabelName, "))");
                        }


                        GUI.Label(new Rect(new Vector2(editorPos.x, editorPos.y + 475 + i * 25), new Vector2(200, 50)), effLabelName);

                        if (GUI.Button(new Rect(new Vector2(editorPos.x + 110, editorPos.y + 475 + i * 25),
                                                new Vector2(45, 15)), "Edit"))
                        {
                            ConditionEditorWindow.ShowWindow(agent, eff);
                        }

                        if (GUI.Button(new Rect(new Vector2(editorPos.x + 175, editorPos.y + 475 + i * 25),
                                                new Vector2(45, 15)), "Delete"))
                        {
                            selectedPT.deleteEffect(eff);
                            ConditionEditorWindow.GetWindow <ConditionEditorWindow>().Close();
                        }
                    }
                }

                GUI.EndScrollView();


                if (selectedPT.effects.Count == 0)
                {
                    AddButtonPos = new Vector2(editorPos.x, editorPos.y + 500);
                }

                else if (selectedPT.effects.Count > 0)
                {
                    AddButtonPos = new Vector2(editorPos.x, editorPos.y + 550);
                }

                if (GUI.Button(new Rect(AddButtonPos,
                                        new Vector2(75, 20)),
                               "Add"))
                {
                    Atom eff = new Atom("New Effect");

                    selectedPT.addEffect(eff);

                    ConditionEditorWindow.ShowWindow(agent, eff);
                }



                GUI.Label(new Rect(new Vector2(editorPos.x, editorPos.y + 600), new Vector2(120, 20)), "Ground Action", labelStyle);


                string[] actionsOptions = { "Move", "Animate", "Custom" };

                if (selectedPT.actionType == ActionTypes.MOVEMENT)
                {
                    actionIndex = 0;
                }
                else if (selectedPT.actionType == ActionTypes.ANIMATION)
                {
                    actionIndex = 1;
                }
                else if (selectedPT.actionType == ActionTypes.CUSTOM)
                {
                    actionIndex = 2;
                }


                //if (GUI.Button (new Rect(new Vector2(editorPos.x, editorPos.y + 500), new Vector2(200,20)),"Edit Action"));
                actionIndex = EditorGUI.Popup(new Rect(new Vector2(editorPos.x, editorPos.y + 625), new Vector2(100, 20)), actionIndex, actionsOptions);

                /*if (selectedPT.groundData == null)
                 *      selectedPT.groundData = new GroundData();*/

                if (actionIndex == 0)
                {
                    selectedPT.actionType = ActionTypes.MOVEMENT;

                    GUI.Label(new Rect(new Vector2(editorPos.x + 110, editorPos.y + 625), new Vector2(100, 20)), "Speed");


                    selectedPT.groundData.speed = EditorGUI.FloatField(new Rect(new Vector2(editorPos.x + 160, editorPos.y + 625), new Vector2(50, 20)), selectedPT.groundData.speed);


                    GUI.Label(new Rect(new Vector2(editorPos.x + 220, editorPos.y + 625), new Vector2(100, 20)), "Radius");


                    selectedPT.groundData.radius = EditorGUI.FloatField(new Rect(new Vector2(editorPos.x + 270, editorPos.y + 625), new Vector2(50, 20)), selectedPT.groundData.radius);


                    if (agent.gameObject.GetComponent <Animator>() != null)
                    {
                        GUI.Label(new Rect(new Vector2(editorPos.x + 110, editorPos.y + 650), new Vector2(100, 20)), "Animation ");


                        selectedPT.groundData.animationState = GUI.TextField(new Rect(new Vector2(editorPos.x + 180, editorPos.y + 650), new Vector2(50, 20)), selectedPT.groundData.animationState);
                    }
                }

                else if (actionIndex == 1)
                {
                    selectedPT.actionType = ActionTypes.ANIMATION;

                    if (agent.gameObject.GetComponent <Animator>() != null)
                    {
                        GUI.Label(new Rect(new Vector2(editorPos.x + 110, editorPos.y + 625), new Vector2(100, 20)), "State");

                        selectedPT.groundData.animationState = GUI.TextField(new Rect(new Vector2(editorPos.x + 150, editorPos.y + 625), new Vector2(75, 20)),
                                                                             selectedPT.groundData.animationState);
                    }
                }

                else if (actionIndex == 2)
                {
                    selectedPT.actionType = ActionTypes.CUSTOM;


                    selectedPT.groundData.name = GUI.TextField(new Rect(new Vector2(editorPos.x + 110, editorPos.y + 625), new Vector2(75, 20)),
                                                               selectedPT.groundData.name.ToString());

                    if (GUI.Button(new Rect(new Vector2(editorPos.x + 200, editorPos.y + 625),
                                            new Vector2(100, 20)), "Create/Open"))
                    {
                        if (!File.Exists("Assets/Actions/" + (string)selectedPT.groundData.name + ".cs"))
                        {
                            using (var stream = new StreamWriter("Assets/Actions/" + (string)selectedPT.groundData.name + ".cs")) {
                                stream.Write(
                                    @"using UnityEngine;
using System;
using System.Collections;


public class " + (string)selectedPT.groundData.name + @": PrimitiveTask, IGroundAction
{
		GameObject agentObj;

		public "         + (string)selectedPT.groundData.name + @"(HTNAgent a, string n){

		name = n;
		agentObj = a.gameObject;	

	}


	public string Name{

		get{return name;}
		set {name = value;}
	}

	//This starts agent's action execution
	public void Start(ActionManager manager, State state){
		

		
		//Monitor precondition validity in current state: if not valid, notify to manager
		if (preconditions.Count > 0 && !RuleMatcher.MatchCondition (preconditions, state,logicalOperator))
			manager.NotValid ();
		
		

		else {
			
			foreach (CuncurrentTask cuncurrent in cuncurrentTasks)
				if (!CheckCuncurrency (cuncurrent,agentObj.GetComponent<HTNAgent>())){

						manager.Suspend ();

						return;
					}

		
			//Add custom code
		}
		
	}


	//Runs at every frame during action's execution
	public void Update(ActionManager manager, State state){
		

		
		//Monitor preconditions validity in current state: if not valid, notify to manager
		if (preconditions.Count > 0 && !RuleMatcher.MatchCondition (preconditions, state,logicalOperator))
			manager.NotValid ();

		
		else {

			foreach (CuncurrentTask cuncurrent in cuncurrentTasks)
				if (!CheckCuncurrency (cuncurrent,agentObj.GetComponent<HTNAgent>())){

						manager.Suspend ();

						return;
					}

			//Add custom code

		}
		
	}

	public void OnComplete(ActionManager manager, State state){

		//Add custom code


		//Flag as completed
		completed = true;

		//Apply effects
		foreach (Atom atom in effects){
			
			Atom fact = new Atom(atom.name,atom.sign);
			
			foreach (Term var in atom.terms)
				fact.addTerm(new Term(var.value));
			

			Atom existingFact = state.Contains(fact);

			if (state.Contains(fact) == null)
				state.addFact(fact);
			else 
				existingFact.sign = fact.sign;
		}


		//Call next action
		manager.NextAction ();
	}

}");

                                stream.Close();
                            }
                        }

                        UnityEditorInternal.InternalEditorUtility.OpenFileAtLineExternal("Assets/Actions/" + (string)selectedPT.groundData.name + ".cs", 1);
                    }
                }
            }


            else if (selected.type == itemType.METHOD)
            {
                Method selectedM = (Method)selected.item;


                GUI.Label(new Rect(editorPos, itemSize), "Name", labelStyle);

                selectedM.name = GUI.TextField(new Rect(new Vector2(editorPos.x + 50, editorPos.y), new Vector2(75, 20)),
                                               selectedM.name);


                if (AtomListWindow.atomNames.list.Count > 0)
                {
                    GUI.Label(new Rect(new Vector2(editorPos.x, editorPos.y + 75), itemSize), "Preference", labelStyle);

                    string[] options = new string[PersonalityEditorWindow.personalities.list.Count + 2];

                    options [0] = "none";

                    PersonalityEditorWindow.personalities.list.CopyTo(options, 1);



                    persIndex = new List <string>(options).IndexOf(selectedM.preference);



                    persIndex = EditorGUI.Popup(new Rect(new Vector2(editorPos.x + 100, editorPos.y + 75), itemSize), persIndex, options);

                    selectedM.preference = options[persIndex];
                }



                GUI.Label(new Rect(new Vector2(editorPos.x, editorPos.y + 125), new Vector2(120, 20)), "Preconditions", labelStyle);



                GUI.Label(new Rect(new Vector2(editorPos.x, editorPos.y + 150), new Vector2(120, 20)), "Logical operator");


                string[] operatorOptions = new string[] { "AND", "OR" };

                int selectedOperator = Array.IndexOf <string> (operatorOptions, selectedM.logicalOperator.ToString());

                selectedOperator = EditorGUI.Popup(new Rect(new Vector2(editorPos.x + 100, editorPos.y + 150), new Vector2(50, 20)),
                                                   selectedOperator, operatorOptions);
                if (selectedOperator == 0)
                {
                    selectedM.logicalOperator = LogicalOperator.AND;
                }
                else if (selectedOperator == 1)
                {
                    selectedM.logicalOperator = LogicalOperator.OR;
                }



                scrollPositionMethoPre = GUI.BeginScrollView(new Rect(new Vector2(editorPos.x, editorPos.y + 175), new Vector2(300, 100)),
                                                             scrollPositionMethoPre, new Rect(new Vector2(editorPos.x, editorPos.y + 175),
                                                                                              new Vector2(275, 100 + selectedM.preconditions.Count * 25)), false, false);


                int i = 0;

                if (selectedM.preconditions.Count > 0)
                {
                    for (i = 0; i < selectedM.preconditions.Count; i++)
                    {
                        Atom pre = selectedM.preconditions[i];

                        string preLabelName = "";

                        if (pre.sign == false)
                        {
                            preLabelName = string.Concat("NOT(", pre.name, "(");
                        }
                        else if (pre.sign == true)
                        {
                            preLabelName = string.Concat(pre.name, "(");
                        }

                        foreach (Term var in pre.terms)
                        {
                            preLabelName = string.Concat(preLabelName, var.key);

                            if (pre.terms.IndexOf(var) < pre.terms.Count - 1)
                            {
                                preLabelName = string.Concat(preLabelName, ",");
                            }
                        }

                        if (pre.sign == true)
                        {
                            preLabelName = string.Concat(preLabelName, ")");
                        }
                        else if (pre.sign == false)
                        {
                            preLabelName = string.Concat(preLabelName, "))");
                        }


                        GUI.Label(new Rect(
                                      new Vector2(editorPos.x, editorPos.y + 200 + i * 25), new Vector2(200, 50)), preLabelName);



                        if (GUI.Button(new Rect(new Vector2(editorPos.x + 110, editorPos.y + 200 + i * 25),
                                                new Vector2(45, 15)), "Edit"))
                        {
                            ConditionEditorWindow.ShowWindow(agent, pre);
                        }

                        if (GUI.Button(new Rect(new Vector2(editorPos.x + 175, editorPos.y + 200 + i * 25),
                                                new Vector2(45, 15)), "Delete"))
                        {
                            selectedM.deletePrecondition(pre);

                            ConditionEditorWindow.GetWindow <ConditionEditorWindow>().Close();
                        }
                    }
                }

                GUI.EndScrollView();


                Vector2 AddButtonPos = new Vector2(0, 0);

                if (selectedM.preconditions.Count == 0)
                {
                    AddButtonPos = new Vector2(editorPos.x, editorPos.y + 175);
                }

                else if (selectedM.preconditions.Count > 0)
                {
                    AddButtonPos = new Vector2(editorPos.x, editorPos.y + 275);
                }


                if (GUI.Button(new Rect(AddButtonPos,
                                        new Vector2(75, 20)),
                               "Add "))
                {
                    Atom pre = new Atom("New Condition");

                    selectedM.addPrecondition(pre);

                    ConditionEditorWindow.ShowWindow(agent, pre);
                }
            }
        }
    }
예제 #6
0
    //-----------------------------------------------------------------------------------------------
    private static void ParseEffectForPrimitiveTask(XmlNode effectNode, PrimitiveTask task)
    {
        EffectProperty effect = ParseEffectFromNode(effectNode);

        task.AddEffect(effect);
    }
예제 #7
0
    //-----------------------------------------------------------------------------------------------
    private static void ParsePreconditionForPrimitiveTask(XmlNode preconditionNode, PrimitiveTask task)
    {
        PreconditionProperty precondition = ParsePreconditionFromNode(preconditionNode);

        task.AddPrecondition(precondition);
    }