Newer
Older
TheVengeance-Project-IADE-Unity2D / Assets / Scripts / NPC / FOV / FOV.cs
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;
}