private void ExecutePlan() { plan = plan != null ? plan : planner.GeneratePlan(currentGoal, state.DeepClone(), actions); if (plan == null) { Debug.Log("Re-Plan"); idleAction.act(agent, state); return; } if (currentAction == null) { currentAction = plan.getNextAction(); agent.actionProgress = 0; } if (currentAction == null || !currentAction.ValidateState(state) || plan.goal != currentGoal) { plan = null; return; } if (currentAction.act(agent, state)) { currentAction = null; } }
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; } } }