private void CreateIdleState() { m_IdleState = (fsm) => { // GOAP planning // get the world state and the goal we want to plan for Dictionary <string, object> worldState = m_DataProvider.GetWorldState(); Dictionary <string, object> goal = m_DataProvider.CreateGoalState(); // Plan Queue <GoapAction> plan = planner.Plan(m_AvailableActions, worldState, goal); if (plan != null) { // we have a plan, hooray! m_CurrentActions = plan; m_DataProvider.PlanFound(goal, plan); fsm.PopState(); // move to PerformAction state fsm.PushState(m_PerformActionState); } else { // ugh, we couldn't get a plan Debug.Log("<color=orange>Failed Plan:</color>" + PrettyPrint(goal)); m_DataProvider.PlanFailed(goal); fsm.PopState(); // move back to IdleAction state fsm.PushState(m_IdleState); } }; }
private void CreateMoveToState() { m_MoveToState = (fsm) => { // move the game object GoapAction action = m_CurrentActions.Peek(); if (action.RequiresInRange() && action.target == null) { Debug.Log("Target not found yet, moving to idle state"); fsm.PopState(); // move fsm.PopState(); // perform fsm.PushState(m_IdleState); return; } // get the agent to move itself if (m_DataProvider.MoveAgent(action)) { fsm.PopState(); } }; }
private void CreatePerformActionState() { m_PerformActionState = (fsm) => { // perform the action if (!HasActionPlan()) { // no actions to perform Debug.Log("<color=red>Done actions</color>"); fsm.PopState(); fsm.PushState(m_IdleState); m_DataProvider.ActionsFinished(); return; } GoapAction action = m_CurrentActions.Peek(); if (action.IsDone()) { // the action is done. Remove it so we can perform the next one m_CurrentActions.Dequeue(); } if (HasActionPlan()) { // perform the next action action = m_CurrentActions.Peek(); if (action.target == null) { action.SetTarget(); } bool inRange = false; if (action.target != null) { inRange = action.RequiresInRange() ? action.IsInRange() : true; } if (inRange) { // we are in range, so perform the action bool success = action.Perform(); if (!success) { // action failed, we need to plan again fsm.PopState(); fsm.PushState(m_IdleState); m_DataProvider.PlanAborted(action); } } else { // we need to move there first // push moveTo state fsm.PushState(m_MoveToState); } } else { // no actions left, move to Plan state fsm.PopState(); fsm.PushState(m_IdleState); m_DataProvider.ActionsFinished(); } }; }