示例#1
0
 protected virtual void OnDisable()
 {
     if (reGoapNode != null)
     {
         reGoapNode.action.Exit();
         reGoapNode = null;
         reGoapNodeList.Clear();
     }
 }
示例#2
0
    public ReGoapNode(IGoapPlanner planner, ReGoapState newGoal, ReGoapNode parent, IReGoapAction action)
    {
        this.planner = planner;
        this.parent  = parent;
        this.action  = action;
        if (action != null)
        {
            actionSettings = action.GetSettings(planner.GetCurrentAgent(), goal);
        }

        if (this.parent != null)
        {
            state = this.parent.GetState();
            // g(node)
            g = parent.GetPathCost();
        }
        else
        {
            state = planner.GetCurrentAgent().GetMemory().GetWorldState();
        }

        var nextAction = parent == null ? null : parent.action;

        if (action != null)
        {
            // backward search does NOT support negative preconditions
            // since in backward search we relax the problem all preconditions are valid but are added to the current goal
            var preconditions = action.GetPreconditions(newGoal, nextAction);
            goal = newGoal + preconditions;

            var effects = action.GetEffects(newGoal, nextAction);
            state += effects;
            g     += action.GetCost(newGoal, nextAction);

            // removing current action effects from goal, no need to do with to the whole state
            //  since the state is the sum of all the previous actions's effects.
            var missingState = new ReGoapState();
            goal.MissingDifference(effects, ref missingState);
            goal = missingState;

            // this is needed every step to make sure that any precondition is not already satisfied
            //  by the world state
            var worldMissingState = new ReGoapState();
            goal.MissingDifference(planner.GetCurrentAgent().GetMemory().GetWorldState(), ref worldMissingState);
            goal = worldMissingState;
        }
        else
        {
            var diff = new ReGoapState();
            newGoal.MissingDifference(state, ref diff);
            goal = diff;
        }
        h = goal.Count;
        // f(node) = g(node) + h(node)
        cost = g + h * heuristicMultiplier;
    }
示例#3
0
    public static ReGoapNode <T, W> Instantiate(IGoapPlanner <T, W> planner, ReGoapState <T, W> newGoal, ReGoapNode <T, W> parent, IReGoapAction <T, W> action)
    {
        if (cachedNodes == null)
        {
            cachedNodes = new Stack <ReGoapNode <T, W> >();
        }
        ReGoapNode <T, W> node = cachedNodes.Count > 0 ? cachedNodes.Pop() : new ReGoapNode <T, W>();

        node.Init(planner, newGoal, parent, action);
        return(node);
    }
示例#4
0
        private void OnDonePlanning(Queue <ReGoapNode> _reGoapNodeList)
        {
            startedPlanning = false;

            if (_reGoapNodeList.Count <= 0)
            {
                return;
            }

            if (reGoapNode != null)
            {
                reGoapNode.action.Exit();
                reGoapNode = null;
            }

            reGoapNodeList = _reGoapNodeList;

            PushAction();
        }
        protected virtual void Awake()
        {
            ReGoapNode <T, W> .Warmup(NodeWarmupCount);

            ReGoapState <T, W> .Warmup(StatesWarmupCount);

            ReGoapLogger.Level = LogLevel;
            if (Instance != null)
            {
                Destroy(this);
                var errorString =
                    "[GoapPlannerManager] Trying to instantiate a new manager but there can be only one per scene.";
                ReGoapLogger.LogError(errorString);
                throw new UnityException(errorString);
            }
            Instance = this;

            doneWorks = new List <ReGoapPlanWork <T, W> >();
            ReGoapPlannerThread <T, W> .WorksQueue = new Queue <ReGoapPlanWork <T, W> >();
            planners = new ReGoapPlannerThread <T, W> [ThreadsCount];
            threads  = new Thread[ThreadsCount];

            if (MultiThread)
            {
                ReGoapLogger.Log(String.Format("[GoapPlannerManager] Running in multi-thread mode ({0} threads).", ThreadsCount));
                for (int i = 0; i < ThreadsCount; i++)
                {
                    planners[i] = new ReGoapPlannerThread <T, W>(PlannerSettings, OnDonePlan);
                    var thread = new Thread(planners[i].MainLoop);
                    thread.Start();
                    threads[i] = thread;
                }
            } // no threads run
            else
            {
                ReGoapLogger.Log("[GoapPlannerManager] Running in single-thread mode.");
                planners[0] = new ReGoapPlannerThread <T, W>(PlannerSettings, OnDonePlan);
            }
        }
示例#6
0
        protected virtual void PushAction()
        {
            if (reGoapNode != null)
            {
                reGoapNode.action.Exit();
                reGoapNode = null;
            }

            if (reGoapNodeList.Count <= 0)
            {
                return;
            }

            if (reGoapNodeList.Count == 0)
            {
                CalculateNewGoal();
            }
            else
            {
                reGoapNode = reGoapNodeList.Dequeue();
                reGoapNode.action.Run(reGoapNode.actionSettings, DoActionEnd, WarnActionFailure);
            }
        }
示例#7
0
    public IReGoapGoal <T, W> Plan(IReGoapAgent <T, W> agent, IReGoapGoal <T, W> blacklistGoal = null, Queue <ReGoapActionState <T, W> > currentPlan = null, Action <IReGoapGoal <T, W> > callback = null)
    {
        ReGoapLogger.Log("[ReGoalPlanner] Starting planning calculation for agent: " + agent);
        goapAgent   = agent;
        Calculated  = false;
        currentGoal = null;
        var possibleGoals = new List <IReGoapGoal <T, W> >();

        foreach (var goal in goapAgent.GetGoalsSet())
        {
            if (goal == blacklistGoal)
            {
                continue;
            }
            goal.Precalculations(this);
            if (goal.IsGoalPossible())
            {
                possibleGoals.Add(goal);
            }
        }
        possibleGoals.Sort((x, y) => x.GetPriority().CompareTo(y.GetPriority()));

        while (possibleGoals.Count > 0)
        {
            currentGoal = possibleGoals[possibleGoals.Count - 1];
            possibleGoals.RemoveAt(possibleGoals.Count - 1);
            var goalState = currentGoal.GetGoalState();

            // can't work with dynamic actions, of course
            if (!settings.UsingDynamicActions)
            {
                var wantedGoalCheck = currentGoal.GetGoalState();
                // we check if the goal can be archived through actions first, so we don't brute force it with A* if we can't
                foreach (var action in goapAgent.GetActionsSet())
                {
                    action.Precalculations(goapAgent, goalState);
                    if (!action.CheckProceduralCondition(goapAgent, wantedGoalCheck))
                    {
                        continue;
                    }
                    // check if the effects of all actions can archieve currentGoal
                    var previous = wantedGoalCheck;
                    wantedGoalCheck = ReGoapState <T, W> .Instantiate();

                    previous.MissingDifference(action.GetEffects(wantedGoalCheck), ref wantedGoalCheck);
                }
                // can't validate goal
                if (wantedGoalCheck.Count > 0)
                {
                    currentGoal = null;
                    continue;
                }
            }

            goalState = (ReGoapState <T, W>)goalState.Clone();
            var leaf = (ReGoapNode <T, W>)astar.Run(
                ReGoapNode <T, W> .Instantiate(this, goalState, null, null), goalState, settings.MaxIterations, settings.PlanningEarlyExit);
            if (leaf == null)
            {
                currentGoal = null;
                continue;
            }
            var path = leaf.CalculatePath();
            if (currentPlan != null && currentPlan == path)
            {
                currentGoal = null;
                break;
            }
            currentGoal.SetPlan(path);
            break;
        }
        Calculated = true;

        if (callback != null)
        {
            callback(currentGoal);
        }
        if (currentGoal != null)
        {
            ReGoapLogger.Log(string.Format("[ReGoapPlanner] Calculated plan for goal '{0}', plan length: {1}", currentGoal, currentGoal.GetPlan().Count));
        }
        else
        {
            ReGoapLogger.LogWarning("[ReGoapPlanner] Error while calculating plan.");
        }
        return(currentGoal);
    }