using System.Collections; using System.Collections.Generic; using UnityEngine; [CreateAssetMenu(menuName = "Finite State Machine/Action/Combat/Ranged/GoToCoverLocation")] public class GoToLocationCoverAction : Action { public override void Execute(FSM fsm) { GameObject target = fsm.Controller.AgentFOV.GetTarget(); Debug.Log($"Execute action: {nameof(GoToLocationCoverAction)}"); if (fsm.CurrentState() is RangedCombatState) { RangedCombatState state = (RangedCombatState)fsm.CurrentState(); if (state.coverObject != null) { Debug.Log($"Go to cover location: {state.coverObject}"); //Calculate the closest point of the cover spot closer to the NPC Vector3 closestPointOnCover = state.coverObject.GetComponent<Collider>().ClosestPoint(fsm.transform.position); //Check the direction from the cover to the target Vector3 coverToPlayerDir = (target.transform.position - closestPointOnCover).normalized; //Check the direction from the cover to the NPC Vector3 coverToNPCDir = (fsm.transform.position - closestPointOnCover).normalized; //Calculate final target position behind cover float dotProduct = Vector3.Dot(coverToPlayerDir, coverToNPCDir); //Calculate the final cover position Vector3 finalCoverPosition = closestPointOnCover; if (dotProduct > 0) { //Calculate the normal of the cover(using the normal of the closest point on the collider) RaycastHit hit; if (Physics.Raycast(closestPointOnCover + Vector3.up, -coverToPlayerDir, out hit)) { finalCoverPosition = hit.point; } } //Set Agent cover destionation fsm.Controller.Agent.SetDestination(finalCoverPosition); } else { Debug.LogError($"There is no Cover Location!"); } } } }