Newer
Older
HierarchicalFSM-Unity3D / Assets / Scripts / NPC / FieldOfView.cs
@Rackday Rackday on 25 Jul 1 KB Enemy FOV
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class FieldOfView : MonoBehaviour
{
    [SerializeField] private float radius;
    [Range(0, 360)]
    [SerializeField] private float angle;
    [SerializeField] private float delay;
    [SerializeField] private Vector3 lastPosition;

    [SerializeField] private GameObject targetRef;

    [SerializeField] private LayerMask targetMask;
    [SerializeField] private LayerMask obstructionMask;

    public float Radius => radius;
    public float Angle => angle;

    // Start is called before the first frame update
    void Start()
    {
        StartCoroutine(FOVRoutine());
    }

    private IEnumerator FOVRoutine()
    {
        WaitForSeconds wait = new WaitForSeconds(delay);

        while (true)
        {
            yield return wait;
            FieldOfViewCheck();
        }
    }

    private void FieldOfViewCheck()
    {
        Collider[] rangeCheck = Physics.OverlapSphere(transform.position, radius, targetMask);

        if (rangeCheck.Length != 0)
        {
            Transform target = rangeCheck[0].transform;
            Vector3 directionToTarget = (target.position - transform.position).normalized;

            if (Vector3.Angle(transform.forward, directionToTarget) < angle / 2)
            {
                float distanceToTarget = Vector3.Distance(transform.position, directionToTarget);

                if (!Physics.Raycast(transform.position, directionToTarget, distanceToTarget, obstructionMask))
                {
                    targetRef = target.gameObject;
                    lastPosition = target.position;
                }
            }
        }

        else targetRef = null;
    }

    //Returns the Last Position the target was seen
    public Vector3 LastPosition() => lastPosition;

    //Returns the current target
    public GameObject GetTarget() => targetRef;
}