コード例 #1
0
        public IGoapGoal Plan(IGoapAgent agent)
        {
            m_agent       = agent;
            m_currentGoal = null;

            List <IGoapGoal> possibleGoals = GetPossibleGoals(agent);

            if (possibleGoals.Count == 0)
            {
                GoapLogger.LogWarning("[ReGoapPlanner] Agent does not have any Goals to perform. " + m_agent.GetName());
            }

            while (possibleGoals.Count > 0)
            {
                m_currentGoal = possibleGoals[possibleGoals.Count - 1];
                possibleGoals.RemoveAt(possibleGoals.Count - 1);

                if (CanFullfillWithActions(m_agent, m_currentGoal) == false)
                {
                    //No actions can't handle this goal
                    GoapLogger.LogWarning("GoalPlanner :: No Actions to handle Goal (" + m_currentGoal.GetName() + ")");
                    m_currentGoal = null;
                    continue;
                }


                GoapState targetState = m_currentGoal.GetGoalState(agent);

                GoapNode <GoapState> leaf = (GoapNode <GoapState>)m_aStar.Run(GoapNode <GoapState> .Instantiate(this, targetState, null, null), targetState);

                if (leaf == null)
                {
                    GoapLogger.LogWarning("GoapPlanner :: Pathfinding failed!");
                    m_currentGoal = null;
                    continue;
                }

                Queue <IGoapAction> actions = leaf.CalculatePath();
                if (actions.Count == 0)
                {
                    GoapLogger.LogWarning("GoapPlanner :: Calculating Path failed!");
                    m_currentGoal = null;
                    continue;
                }

                m_currentGoal.SetPlan(actions);
                break;
            }

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

            return(m_currentGoal);
        }
コード例 #2
0
        public bool CanRunAction(IGoapAgent agent, IGoapAction action)
        {
            action.OnPrepare(agent);

            if (action.ValidateContextPreconditions() == false)
            {
                return(false);
            }
            return(true);
        }
コード例 #3
0
        private List <IGoapGoal> GetPossibleGoals(IGoapAgent agent)
        {
            List <IGoapGoal> possibleGoals = new List <IGoapGoal>();

            foreach (IGoapGoal goal in agent.GetGoals())
            {
                if (CanRunGoal(agent, goal))
                {
                    possibleGoals.Add(goal);
                }
            }

            possibleGoals.Sort((x, y) => x.GetPriority().CompareTo(y.GetPriority()));

            return(possibleGoals);
        }
コード例 #4
0
        private bool CanFullfillWithActions(IGoapAgent agent, IGoapGoal goal)
        {
            GoapState goalState = goal.GetGoalState(agent).Clone();

            foreach (IGoapAction action in agent.GetActions())
            {
                if (CanRunAction(agent, action) == false)
                {
                    continue;
                }

                goalState.RemoveCompletedConditions(action.GetContextPostEffects(goalState));;
            }

            goalState.RemoveCompletedConditions(m_agent.GetMemory().GetWorldState());

            if (goalState.Count > 0)
            {
                return(false);
            }

            return(true);
        }
コード例 #5
0
        public bool CanRunGoal(IGoapAgent agent, IGoapGoal goal)
        {
            if (agent.GetCurrentGoal() == goal)
            {
                return(false);
            }

            if (goal.CanRun(agent) == false)
            {
                return(false);
            }

            GoapState differenceState = goal.GetGoalState(agent).Clone();

            differenceState.RemoveCompletedConditions(m_agent.GetMemory().GetWorldState());

            if (differenceState.Count == 0)
            {
                return(false);
            }


            return(true);
        }
コード例 #6
0
        public List <INode <GoapState> > GetNeighbours()
        {
            m_expandList.Clear();

            IGoapAgent         agent   = m_planner.GetAgent();
            List <IGoapAction> actions = agent.GetActions();

            for (int i = actions.Count - 1; i >= 0; i--)
            {
                IGoapAction possibleAction = actions[i];

                if (possibleAction == m_action)
                {
                    continue;
                }

                if (GoapPlannerManager.s_Instance.GetPlanner().CanRunAction(agent, possibleAction) == false)
                {
                    continue;
                }

                GoapState preConditions = possibleAction.GetContextPreConditions(m_targetState);
                GoapState postEffects   = possibleAction.GetContextPostEffects(m_targetState);

                bool isValid = (postEffects.HasAny(m_targetState)) &&
                               (!m_targetState.HasAnyConflict(preConditions)) && (!m_targetState.HasAnyConflict(postEffects));

                if (isValid)
                {
                    GoapState targetState = m_targetState;
                    m_expandList.Add(Instantiate(m_planner, targetState, this, possibleAction));
                }
            }

            return(m_expandList);
        }
コード例 #7
0
 public override void OnPrepare(IGoapAgent agent)
 {
     m_isInitialized = false;
     base.OnPrepare(agent);
 }
コード例 #8
0
        public IGoapGoal <T, W> Plan(IGoapAgent <T, W> agent, IGoapGoal <T, W> blacklistGoal = null, Queue <GoapActionState <T, W> > currentPlan = null, Action <IGoapGoal <T, W> > callback = null)
        {
            if (GoapLogger.Level == GoapLogger.DebugLevel.Full)
            {
                GoapLogger.Log("[ReGoalPlanner] Starting planning calculation for agent: " + agent);
            }
            goapAgent   = agent;
            Calculated  = false;
            currentGoal = null;
            var possibleGoals = new List <IGoapGoal <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()));

            var currentState = agent.GetMemory().GetWorldState();

            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();
                    GoapActionStackData <T, W> stackData;
                    stackData.agent        = goapAgent;
                    stackData.currentState = currentState;
                    stackData.goalState    = goalState;
                    stackData.next         = null;
                    stackData.settings     = null;
                    // 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(stackData);
                        if (!action.CheckProceduralCondition(stackData))
                        {
                            continue;
                        }
                        // check if the effects of all actions can archieve currentGoal
                        var previous = wantedGoalCheck;
                        wantedGoalCheck = GoapState <T, W> .Instantiate();

                        previous.MissingDifference(action.GetEffects(stackData), ref wantedGoalCheck);
                    }
                    // finally push the current world state
                    var current = wantedGoalCheck;
                    wantedGoalCheck = GoapState <T, W> .Instantiate();

                    current.MissingDifference(GetCurrentAgent().GetMemory().GetWorldState(), ref wantedGoalCheck);
                    // can't validate goal
                    if (wantedGoalCheck.Count > 0)
                    {
                        currentGoal = null;
                        continue;
                    }
                }

                goalState = goalState.Clone();
                var leaf = (GoapNode <T, W>)astar.Run(
                    GoapNode <T, W> .Instantiate(this, goalState, null, null, null), goalState, settings.MaxIterations, settings.PlanningEarlyExit, debugPlan: settings.DebugPlan);
                if (leaf == null)
                {
                    currentGoal = null;
                    continue;
                }

                var result = leaf.CalculatePath();
                if (currentPlan != null && currentPlan == result)
                {
                    currentGoal = null;
                    break;
                }
                if (result.Count == 0)
                {
                    currentGoal = null;
                    continue;
                }
                currentGoal.SetPlan(result);
                break;
            }
            Calculated = true;

            callback?.Invoke(currentGoal);

            if (currentGoal != null)
            {
                GoapLogger.Log(string.Format("[ReGoapPlanner] Calculated plan for goal '{0}', plan length: {1}", currentGoal, currentGoal.GetPlan().Count));
                if (GoapLogger.Level == GoapLogger.DebugLevel.Full)
                {
                    int i = 0;
                    GoapActionStackData <T, W> stackData;
                    stackData.agent        = agent;
                    stackData.currentState = currentState;
                    stackData.goalState    = currentGoal.GetGoalState();
                    stackData.next         = null;
                    foreach (var action in currentGoal.GetPlan())
                    {
                        stackData.settings = action.Settings;
                        GoapLogger.Log(string.Format("[ReGoapPlanner] {0}) {1}", i++, action.Action.ToString(stackData)));
                    }
                }
            }
            else
            {
                GoapLogger.LogWarning("[ReGoapPlanner] Error while calculating plan.");
            }
            return(currentGoal);
        }
コード例 #9
0
 public virtual void OnPrepare(IGoapAgent agent)
 {
     m_agent = agent;
 }
コード例 #10
0
 public virtual bool CanRun(IGoapAgent agent)
 {
     return(true);
 }
コード例 #11
0
 public virtual GoapState GetGoalState(IGoapAgent agent)
 {
     return(m_goalState);
 }