using System; using UnityEngine; // ReSharper disable once CheckNamespace namespace BlueWaterProject { public class FieldOfView : MonoBehaviour { #region Property and variable [Header("타겟 및 시야 설정")] [SerializeField] private bool drawGizmo = true; [SerializeField] private LayerMask targetLayer; [Tooltip("시야 각도\n상대를 감지하는 0~360도 사이의 시야각")] [Range(0f, 360f)] [SerializeField] private float viewAngle = 360f; [Tooltip("시야 길이\n상대를 감지하는 최대 길이, 부채꼴 혹은 원의 반지름 길이")] [Range(0f, 50f)] [SerializeField] private float viewRadius; [Header("시야 내 타겟 정보")] [SerializeField] private Collider[] colliderWithinRange = new Collider[TARGET_MAX_SIZE]; [SerializeField] private Transform targetTransform; private const int TARGET_MAX_SIZE = 20; #endregion #region Unity built-in Function #if UNITY_EDITOR public void OnDrawGizmosSelected() { if (!drawGizmo) return; var myPos = transform.position; Gizmos.color = Color.green; Gizmos.DrawWireSphere(myPos, viewRadius); if (targetTransform == null) return; Debug.DrawLine(myPos, targetTransform.position, Color.red); } #endif private void LateUpdate() { Array.Clear(colliderWithinRange, 0, TARGET_MAX_SIZE); var myPos = transform.position; var maxColliderCount = Physics.OverlapSphereNonAlloc(myPos, viewRadius, colliderWithinRange, targetLayer, QueryTriggerInteraction.Collide); if (maxColliderCount <= 0) { targetTransform = null; return; } var nearestDistance = Vector3.Distance(colliderWithinRange[0].transform.position, myPos); var nearestTargetTransform = colliderWithinRange[0].transform; for (var i = 1; i < maxColliderCount; i++) { var distance = Vector3.Distance(colliderWithinRange[i].transform.position, myPos); if (nearestDistance < distance) continue; nearestDistance = distance; nearestTargetTransform = colliderWithinRange[i].transform; } targetTransform = nearestTargetTransform; if (!targetTransform) return; var targetPos = targetTransform.position; targetPos.y = transform.position.y; transform.LookAt(targetPos); } #endregion #region Custom Function public int GetTargetLayer() => targetLayer; public Transform GetTargetTransform() => targetTransform; #endregion } }