/// <summary> /// Add am action to the queue or set it as the current action /// </summary> /// <param name="actionName">The name of the action in the PossiblActions queue</param> /// <param name="addToList">Whether to add it to the list or set as current action</param> /// <param name="go">GameObejct to be passed to the action</param> /// <param name="vec3">Vector3 to be passed to the action</param> /// <param name="integer">Integer to be passed to the action</param> public void AddAction(string actionName, bool addToList, GameObject go, Vector3 vec3, int integer) { // Check whether the action is valid if (PossibleActionsDict.ContainsKey(actionName)) { AIAction action = PossibleActionsDict[actionName]; if (action) { // Get a copy action = Instantiate(action); // Initialise action.InitialiseAction(this); // Set the internal data of the action and see if it can be performed if (action.SetVariables(this, go, vec3, integer)) { // If it can be performed then handle it appropriately SetAction(action, addToList, false); } else { // Else cancel the action and move on action.CancelAction(this); } } } }
/// <summary> /// Instantiate, initialise and 'select' an action the add to the queue or set as current, will not be added if it's selection fails /// </summary> /// <param name="action">Action to add</param> /// <param name="addToList">Whether to add to the queue or not</param> /// <param name="selectAction">Whether to call the SelectAction method on the action or not</param> /// <param name="createInstance">Whether or not to instantiate the action</param> public void AddAction(AIAction action, bool addToList, bool selectAction = true, bool createInstance = true) { cachedAction = action; if (cachedAction) { bool selectedPass = false; if (createInstance) { // Instantiate and initialise the new action cachedAction = Instantiate(cachedAction); cachedAction.InitialiseAction(this); } if (selectAction) { selectedPass = cachedAction.SelectionAction(this); if (!selectedPass) { cachedAction.CancelAction(this); } } if (selectedPass || !selectAction) { SetAction(cachedAction, addToList); } } }
/// <summary> /// Determines the best action to perform /// </summary> /// <returns></returns> public AIAction GetBestAction() { AIAction highestAction = null; float highestEvaluation = 0; // If there is a current action, it is by default the most valuable action to start if (CurrentAction) { highestAction = CurrentAction; highestEvaluation = CurrentAction.EvaluateAction(this); } // Loop through possible actions and evaluate them foreach (AIAction action in PossibleActions) { float evaluateVal = action.EvaluateAction(this); DebugManager.LogMessage($"Action {action.name} evaluated with value: {evaluateVal}"); if (evaluateVal > highestEvaluation) { highestEvaluation = evaluateVal; highestAction = action; } } return(highestAction); }
public void UpdateAction() { // If there is a current action, update it if (CurrentAction) { CurrentAction.UpdateAction(this); // If the current action has completed, move on to the next action in the queue if (CurrentAction.HasActionCompleted(this)) { CurrentAction.ExitAction(this); // Get the next action from the queue if there is one if (ActionQueue.Count > 0) { CurrentAction = ActionQueue[0]; CurrentAction.EnterAction(this); CurrentAction.ExecuteAction(this); ActionQueue.RemoveAt(0); } else { CurrentAction = null; } RefreshActionRefs(); } } }
// Make a copy public ActionInput(ActionInput selectorInput) { if (selectorInput == null) { return; } SelectorInputName = selectorInput.SelectorInputName; InputActionRef = selectorInput.InputActionRef; Action = selectorInput.Action; }
/// <summary> /// This will take an action and either set the current action or add it to the queue /// </summary> /// <param name="action">Action to add</param> /// <param name="addToList">If set to false, will set the current action. Otherwise will add to queue</param> public void SetAction(AIAction action, bool addToList, bool checkInList = true) { if (!action) { return; } if (CurrentAction && CurrentAction.Equals(action) && checkInList) { return; } // If there is no current action or queued action, then just et the current action if (!CurrentAction && ActionQueue.Count == 0) { CurrentAction = action; addToList = false; } // Else if there is a current action, or a queued action, add to the queue else if (addToList) { ActionQueue.Add(action); } // Otherwise, reset the queue and set the current action else { // Exit out of current action if there is one if (CurrentAction) { CurrentAction.ExitAction(this); } // Cancel queued actions Helper.LoopList_ForEach <AIAction>(ActionQueue, (AIAction a) => { a.CancelAction(this); }); ActionQueue.Clear(); CurrentAction = action; } // Enter and execute the new current action, if there is one if (!addToList && CurrentAction) { CurrentAction.EnterAction(this); CurrentAction.ExecuteAction(this); } RefreshActionRefs(); }
/// <summary> /// Clears the current action and the queue and then refreshes clients /// </summary> /// <param name="refresh"></param> public void ClearAllActions(bool refresh = true) { // If there is a current action then exit it and set to null if (CurrentAction) { CurrentAction.ExitAction(this); CurrentAction = null; } // Loop through the queue and cancel each action Helper.LoopList_ForEach <AIAction>(ActionQueue, (AIAction a) => { a.CancelAction(this); }); ActionQueue.Clear(); // Refresh ActionRefs if (refresh) { RefreshActionRefs(); } }
// Start is called before the first frame update protected override IEnumerator Start() { yield return(base.Start()); if (!Agent) { Agent = gameObject.GetComponent <AIAgent>(); } // If this unit is using the set of default actions then add them to this unit's list of available actions if (UseDefaultActions) { Helper.LoopList_ForEach <ActionInput>(DefaultUnitHandler.Instance.SelectionInputs, (ActionInput s) => { ActionInputs.Add(new ActionInput(s)); }); } AIAction tempAction = null; Helper.LoopList_ForEach <ActionInput>(ActionInputs, (ActionInput s) => { // Get a copy of the action associated and add it to the AIAgent's dictionary of possible actions tempAction = s.GetActionClone; if (tempAction) { Agent.SetActionInDict(s.ActionName, tempAction, true); Agent.PossibleActions.Add(tempAction); } // Set up the input callback for this action DefaultUnitHandler.AddPerformedAction(s, PerformedAction); }); if (DefaultUnitHandler.Instance.ClearActionQueueInput) { ClearActionInput.PerformedActions += (InputAction.CallbackContext cc) => { NetworkHandler.ClientInstance.CmdClearActions(Agent.gameObject); }; } }
/// <summary> /// Set an action in the PossibleActionsDict /// </summary> /// <param name="actionName">Name of the action</param> /// <param name="action">Action to set</param> /// <param name="overwrite">Whether or not to replace a value that is already in the dictionary</param> public void SetActionInDict(string actionName, AIAction action, bool overwrite = false) { Helper.SetInDictionary <string, AIAction>(ref PossibleActionsDict, actionName, action, overwrite); }