using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.AI; [CreateAssetMenu(menuName = "Finite State Machine/Condition/TryToFindCoverLocation")] public class TryToFindCoverLocation : Condition { [SerializeField] private CheckTargetState targetState; [SerializeField] private string tag; //Target object tab [SerializeField] private ushort numberOftries = 3; //Number of try checks to find a cover location public override bool CheckCondition(FSM fsm) { Debug.Log("CheckCondition"); //Checks if the target is on specific state if (targetState.CheckCondition(fsm)) { return FindSpot(fsm) ? true : false; } else return false; } //tris to find a cover location for the NPC private GameObject FindSpot(FSM fsm) { Awareness agentAware = fsm.Controller.AgentAwareness; GameObject target = fsm.Controller.AgentFOV.GetTarget(); if (agentAware != null && target != null) { //Use the sensor agentAware.SetTargetTag(tag); agentAware.enabled = true; if (agentAware.TargetsList.Count > 0) { //Closest target float closestTargetDistance = float.MaxValue; GameObject coverObj = null; foreach (GameObject g in agentAware.TargetsList) { float distance = Vector3.Distance(fsm.transform.position, g.transform.position); if (distance < closestTargetDistance || distance <= 0f) { if (IsSpotProtected(target.transform, coverObj.transform)) { coverObj = g; closestTargetDistance = distance; } } } return coverObj; } return null; } return null; } //If there are any available spots check if the spot protects from the player private bool IsSpotProtected(Transform target, Transform coverObject) { RaycastHit hit; //Checks if either target or cover object is not null if (target != null && coverObject != null) { //Calculates the direction Vector3 directionToPlayer = (target.position - coverObject.position).normalized; //Performs the raycast to check if the cover object will provide actual cover to the NPC if (Physics.Raycast(coverObject.position, directionToPlayer, out hit)) { return hit.transform != target; } Debug.LogWarning($"Raycast failed for cover check."); return false; } else { Debug.LogWarning($"Missing: {nameof(target)} or {nameof(coverObject)}"); return false; } } }