using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; using Cysharp.Threading.Tasks; using Unity.Mathematics; using UnityEngine; namespace BITKit.Sensors { public class RaySensor : Sensor { [Header(Constant.Header.Settings)] [SerializeField] private float radius = 0.16f; public float distance; public override IEnumerable Get() => detected.ValueArray; private readonly RaycastHit[] raycasts = new RaycastHit[16]; private readonly Queue<(Vector3,Vector3)> _drawGizmosQueue = new(); private readonly CacheList detected = new(); public override UniTask Execute(float delta) { var _transform = transform; var forward = _transform.forward; var position = _transform.position; var size = 0; if (radius is not 0) { size = Physics.CapsuleCastNonAlloc(position, position + forward * distance, radius, forward, raycasts , distance, detectLayer); } else { var ray = new Ray(_transform.position, _transform.forward); size = Physics.RaycastNonAlloc(ray, raycasts, distance, detectLayer); } //var reportBuilder = new StringBuilder(); detected.Clear(); foreach (var hit in raycasts .Take(size) .Where(IsValid) .OrderBy(ByDistance)) { detected.Add(hit.transform); } //Debug.Log(reportBuilder); return UniTask.CompletedTask; float ByDistance(RaycastHit arg) { var x = Vector3.Distance(arg.point, position); //_drawGizmosQueue.Enqueue(new(arg.collider.bounds.center, arg.point)); //reportBuilder.AppendLine($"Name:{arg.collider.name},Distance:{x}"); return x; } } public bool IsValid(RaycastHit hit) => IsValid(hit.collider); public override bool IsValid(Collider _collider) => ignoreColliders.Contains(_collider) is false; public override float GetDistance() => distance; private void OnDrawGizmosSelected() { while (_drawGizmosQueue.TryDequeue(out var p)) { var (closePoint, point) = p; Gizmos.DrawWireCube(point,Vector3.one*0.01f); Gizmos.DrawLine(closePoint,point); } } } }