private void createPerformActionState() { performActionState = (FiniteStateMachine, gameObj) => { //performs action if (!hasActionPlan()) { //no actions FiniteStateMachine.Pop(); FiniteStateMachine.Push(idleState); dataProvider.actionsFinished(); return; } GOAPAction action = currentActions.Peek(); if (action.isDone()) { //action done currentActions.Dequeue(); } if (hasActionPlan()) { //perform next action action = currentActions.Peek(); bool inRange = action.mustBeInRange() ? action.isInRange() : true; if (inRange) { //in range bool success = action.perform(gameObj); if (!success) { //action failed FiniteStateMachine.Pop(); FiniteStateMachine.Push(idleState); dataProvider.planAborted(action); } } else { //move there first FiniteStateMachine.Push(moveState); } } else { //no actions left FiniteStateMachine.Pop(); FiniteStateMachine.Push(idleState); dataProvider.actionsFinished(); } }; }
private void createPerformActionState() { performActionState = (fsm, gameObj) => { // Perform the action if (!hasActionPlan()) { // No actions to perform fsm.popState(); fsm.pushState(idleState); dataProvider.actionsFinished(); return; } GOAPAction action = currentActions.Peek(); if (action.isDone()) { // The action is done. We can remove it, onto the next one! currentActions.Dequeue(); } if (hasActionPlan()) { // Perform the next action action = currentActions.Peek(); bool inRange = action.requiresInRange() ? action.isInRange() : true; if (inRange) { // We're in range, so perform the action bool success = action.perform(gameObj); if (!success) { // Action failed, we need to plan again fsm.popState(); fsm.pushState(idleState); dataProvider.planAborted(action); } } else { // We need to move to our target first // Let's make the AI move fsm.pushState(moveToTargetState); } } // If all fails, change back to idleState (planning stage) else { fsm.popState(); fsm.pushState(idleState); dataProvider.actionsFinished(); } }; }
//Animation state plays an animation such as shooting, swinging sword. The effect of the animation should be programmed outside of the GOAP system. //The GOAP system only plays animations and moves the agent void animateStateInit() { animateState = (fsm, gameObj) => { GOAPAction action = actionQueue.Peek(); if (action.isDone(this) && actionActivated) { // the action is done. Remove it so we can perform the next one actionActivated = false; actionQueue.Dequeue(); if (actionQueue.Count == 0) { fsm.popState(); fsm.pushState(idleState); } } else { if (action.requiresInRange) { //If an action requires to be in range of a type of object (set by the actions targetTag), we must find one and go to it before playing the animation target = FindClosestTarget(action.targetTag); if (target == null) { //No target. Action failed fsm.popState(); fsm.pushState(idleState); } else { //Only go to the target object if out of range if (Vector3.Distance(target.transform.position, this.transform.position) > action.range) { targetSet = false; fsm.pushState(goToState); } else if (action != currentAction) { //Otherwise activate the action currentAction = action; currentAction.activate(this); actionActivated = true; } } } else if (currentAction != action) { //Activate the current action currentAction = action; currentAction.activate(this); actionActivated = true; } } }; }
private void CreatePerformActionState(GOAPComponent aic) { aic.performActionState = (fsm, obj) => { //aic.AnnouncePerformActionState(); if (!aic.HasActionPlan()) { fsm.popState(); fsm.pushState(aic.idleState); aic.ActionsFinished(); return; } GOAPAction action = aic.currentActions.Peek(); if (action.isDone()) { aic.currentActions.Dequeue(); } if (aic.HasActionPlan()) { action = aic.currentActions.Peek(); bool inRange = action.requiresInRange() ? action.isInRange() : true; if (inRange) { bool success = action.perform(obj); if (!success) { fsm.popState(); fsm.pushState(aic.idleState); CreateIdleState(aic); aic.PlanAborted(action); } } else { fsm.pushState(aic.moveToState); } } else { fsm.popState(); fsm.pushState(aic.idleState); aic.ActionsFinished(); } }; }
private void createPerformActionState() { performActionState = (fsm, obj) => { if (!hasActionPlan()) { fsm.popState(); fsm.pushState(idleState); dataProvider.ActionsFinished(); return; } GOAPAction action = currentActions.Peek(); if (action.isDone()) { currentActions.Dequeue(); } if (hasActionPlan()) { action = currentActions.Peek(); bool inRange = action.requiresInRange() ? action.isInRange() : true; if (inRange) { bool success = action.perform(obj); if (!success) { fsm.popState(); fsm.pushState(idleState); createIdleState(); dataProvider.PlanAborted(action); } } else { fsm.pushState(moveToState); } } else { fsm.popState(); fsm.pushState(idleState); dataProvider.ActionsFinished(); } }; }