using System.Collections; using System.Collections.Generic; using UnityEngine; public abstract class FOV : MonoBehaviour { [Header("FOV Settings: ")] [SerializeField] protected float fovRadius; [Range(0, 360)][SerializeField] protected float angle; [SerializeField] protected float fovDelay; [SerializeField] protected LayerMask targetMask; [SerializeField] protected GameObject target; protected bool isEnabled = true; private NPCController controller; public float Radius => fovRadius; public float Angle => angle; public NPCController Controller => controller; public Vector2 TargetDirection { get { if (target != null) return DirectionToTarget(); else { Debug.LogWarning($"Target is null!"); return Vector2.zero; } } } public float TargetDistance { get { if (target != null) return DistanceToTarget(); else { Debug.LogWarning($"Target is null!"); return DistanceToTarget(); } } } public bool IsEnabled { get => isEnabled; set => isEnabled = value; } protected void Awake() { controller = GetComponent<NPCController>(); isEnabled = true; } // Start is called before the first frame update protected void Start() { StartCoroutine(FOVRoutine(fovDelay)); } protected void OnEnable() { StartCoroutine(FOVRoutine(fovDelay)); } // Update is called once per frame protected void Update() { } protected virtual void PerformFov() { if (target == null && isEnabled) { Collider2D[] colliders = Physics2D.OverlapCircleAll(transform.position, fovRadius, targetMask); if (colliders.Length != 0) { foreach (Collider2D collider in colliders) { GameObject potentialTarget = collider.gameObject; Vector2 dirToTarget = (potentialTarget.transform.position - transform.position).normalized; // Check if the target is within the specified angle if (Vector2.Angle(transform.right, dirToTarget) < angle / 2) { target = potentialTarget; Debug.Log("Target detected within angle!"); return; // Exit after finding the first valid target } } } } } protected IEnumerator FOVRoutine(float seconds) { while (true) { WaitForSeconds wait = new WaitForSeconds(seconds); yield return wait; PerformFov(); } } private Vector2 DirectionToTarget() => (target.transform.position - transform.position).normalized; private float DistanceToTarget() => (target.transform.position - transform.position).magnitude; public GameObject GetTarget() => target; public void SetTarget(GameObject target) => this.target = target; public void ClearTarget() => target = null; }