示例#1
0
    //HTN forward plan builder
    private void BuildPlan()
    {
        node cur;

        tasks = new Queue <node>();
        plan  = new Queue <string>();
        tasks.Enqueue(htn_tree.rootNode);
        while (tasks.Count > 0)
        {
            bool preConditionsMet = false;
            cur = tasks.Dequeue();

            //rootnode is a compound task we need to evaluate regardless of wolrd state
            if (cur.t == node.type.Root)
            {
                compound_task c_cur = (compound_task)cur;
                LoadChildren(c_cur.children);
            }
            //normal compound nodes extraction and evaluation
            else if (cur.t == node.type.Compound)
            {
                compound_task c_cur = (compound_task)cur;
                preConditionsMet = EvalCompoundPreConditions(c_cur.behaviorName);

                if (preConditionsMet == true)
                {
                    //in a sequence all tasks are evaluated
                    if (c_cur.st == compound_task.subType.Sequence)
                    {
                        LoadChildren(c_cur.children);
                    }
                    //in the selector 1 random task is evaluated
                    else if (c_cur.st == compound_task.subType.Selector)
                    {
                        int         index = Random.Range(0, c_cur.children.Count);
                        List <node> l     = new List <node>();
                        l.Add(c_cur.children[index]);
                        LoadChildren(l);
                    }
                }
            }
            //primitive tasks preconditions are evaluated one last time before being added to the execution plan. A failure triggers a replan.
            else if (cur.t == node.type.Primitive)
            {
                primitive_task p_cur = (primitive_task)cur;
                preConditionsMet = EvalPrimitivePreConditions(p_cur.taskName);

                if (preConditionsMet == true)
                {
                    plan.Enqueue(p_cur.taskName);
                }
                else
                {
                    planIsValid = false;
                    break;
                }
            }
        }
    }
示例#2
0
    //default constructor builds the htn tree model in the implementation doc
    public monster_htn()
    {
        monster = GameObject.Find("Monster");
        m       = monster.GetComponent <monster_controller>();

        //define rootNode node
        rootNode          = new compound_task(node.type.Root, "beAMonster");
        rootNode.children = new List <node>();

        rootNode.children.Add(new compound_task(rootNode, node.type.Compound, compound_task.subType.Sequence, "wander"));
        rootNode.children.Add(new compound_task(rootNode, node.type.Compound, compound_task.subType.Sequence, "attack"));

        //build left handside of the htn: wandering behavior
        compound_task wanderNode = (compound_task)rootNode.children[0];

        wanderNode.children = new List <node>
        {
            new compound_task(wanderNode, node.type.Compound, compound_task.subType.Selector, "navSpeed"), //movement type
            new primitive_task(wanderNode, node.type.Primitive, "setNavDest"),                             //choose dest
            new primitive_task(wanderNode, node.type.Primitive, "idle")                                    //rest
        };

        compound_task navSpeedNode = (compound_task)wanderNode.children[0];

        navSpeedNode.children = new List <node>
        {
            new primitive_task(navSpeedNode, node.type.Primitive, "walk"),
            new primitive_task(navSpeedNode, node.type.Primitive, "run")
        };

        //build the right handside of the tree: attack behavior
        compound_task attackNode = (compound_task)rootNode.children[1];

        attackNode.children = new List <node>
        {
            new primitive_task(attackNode, node.type.Primitive, "getAngry"),                                        //change skin color
            new compound_task(attackNode, node.type.Compound, compound_task.subType.Sequence, "findObjectToThrow"), //pick up object
            new compound_task(attackNode, node.type.Compound, compound_task.subType.Selector, "throw"),             //throw
            new primitive_task(wanderNode, node.type.Primitive, "recover")                                          //rest
        };

        compound_task findObjNode = (compound_task)attackNode.children[1];

        findObjNode.children = new List <node>
        {
            new primitive_task(findObjNode, node.type.Primitive, "findObj"),  //find closest obj
            new primitive_task(findObjNode, node.type.Primitive, "navToObj"), //navigate to it
            new primitive_task(findObjNode, node.type.Primitive, "pickUp")    //pick it up
        };

        compound_task throwNode = (compound_task)attackNode.children[2];

        throwNode.children = new List <node>
        {
            new compound_task(throwNode, node.type.Compound, compound_task.subType.Sequence, "superThrow"), //throw rock
            new primitive_task(throwNode, node.type.Primitive, "objectThrow")                               //throw object
        };

        compound_task superThrowNode = (compound_task)throwNode.children[0];

        superThrowNode.children = new List <node>
        {
            new primitive_task(superThrowNode, node.type.Primitive, "growl"),      //growl
            new primitive_task(superThrowNode, node.type.Primitive, "objectThrow") //throw object
        };
    }