Net.Like.Xue.Tokyo/Assets/BITKit/Unity/Scripts/Sensor/RaySensor.cs

76 lines
2.6 KiB
C#

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<Transform> Get() => detected.ValueArray;
private readonly RaycastHit[] raycasts = new RaycastHit[16];
private readonly Queue<(Vector3,Vector3)> _drawGizmosQueue = new();
private readonly CacheList<Transform> 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);
}
}
}
}