1
This commit is contained in:
@@ -7,24 +7,25 @@ using Cysharp.Threading.Tasks;
|
||||
using UnityEngine.Jobs;
|
||||
using UnityEngine.Pool;
|
||||
using UnityEngine.Profiling;
|
||||
using Physics=UnityEngine.Physics;
|
||||
|
||||
namespace BITKit.Sensors
|
||||
{
|
||||
public class RangeSensor : Sensor
|
||||
{
|
||||
[Header(Constant.Header.Settings)]
|
||||
public float radius;
|
||||
[Header(Constant.Header.Settings)] public float radius;
|
||||
public int fov;
|
||||
public bool requireSight;
|
||||
|
||||
[Header(Constant.Header.Settings)]
|
||||
public LayerMask blockLayer;
|
||||
[Header(Constant.Header.InternalVariables)]
|
||||
private FrameUpdate frameUpdater;
|
||||
private readonly Collider[] colliders = new Collider[32];
|
||||
private RaycastHit[] hits;
|
||||
|
||||
private bool isExecuting;
|
||||
[Header(Constant.Header.Settings)] public LayerMask blockLayer;
|
||||
|
||||
[Header(Constant.Header.Debug)] [Header(Constant.Header.InternalVariables)]
|
||||
private FrameUpdate frameUpdater;
|
||||
|
||||
private readonly Collider[] colliders = new Collider[32];
|
||||
private RaycastHit[] hits = new RaycastHit[32];
|
||||
private readonly HashSet<int> tempHashSet = new();
|
||||
|
||||
public override IEnumerable<Transform> Get()
|
||||
{
|
||||
if (!_detectedDoubleBuffer.TryGetRelease(out var newRelease)) return _detectedBuffer;
|
||||
@@ -33,12 +34,13 @@ namespace BITKit.Sensors
|
||||
Profiler.EndSample();
|
||||
return _detectedBuffer;
|
||||
}
|
||||
private readonly DoubleBuffer<IEnumerable<Transform>> _detectedDoubleBuffer=new();
|
||||
private IEnumerable<Transform> _detectedBuffer;
|
||||
|
||||
|
||||
public override UniTask Execute()
|
||||
private readonly DoubleBuffer<IEnumerable<Transform>> _detectedDoubleBuffer = new();
|
||||
private IEnumerable<Transform> _detectedBuffer=Array.Empty<Transform>();
|
||||
|
||||
public override UniTask Execute(float delta)
|
||||
{
|
||||
tempHashSet.Clear();
|
||||
var length = Physics.OverlapSphereNonAlloc(Transform.position, radius, colliders, detectLayer);
|
||||
Profiler.BeginSample("Filter Detected Colliders");
|
||||
var _newDetected = from x in colliders.Take(length) where IsValid(x) select x.transform;
|
||||
@@ -54,7 +56,7 @@ namespace BITKit.Sensors
|
||||
case var _ when ignoreColliders.Contains(_collider):
|
||||
return false;
|
||||
case var _ when fov > 0 && CheckFov(ref _collider) is false:
|
||||
case var _ when requireSight && CheckSight(ref _collider) is false:
|
||||
case var _ when requireSight && CheckSight(ref _collider) is false:
|
||||
return false;
|
||||
default:
|
||||
return true;
|
||||
@@ -62,18 +64,21 @@ namespace BITKit.Sensors
|
||||
}
|
||||
|
||||
public override float GetDistance() => radius;
|
||||
|
||||
private bool CheckFov(ref Collider _collider)
|
||||
{
|
||||
var _dir = _collider.transform.position - transform.position;
|
||||
if (_dir.sqrMagnitude <= 0) return false;
|
||||
var dir = Quaternion.LookRotation(_dir);
|
||||
return Vector3.Dot(transform.forward, _dir) > 0 && fov > Quaternion.Angle(transform.rotation, dir);
|
||||
var _dir = _collider.bounds.center - transform.position;
|
||||
if (_dir.sqrMagnitude <= 0) return false;
|
||||
var dir = Quaternion.LookRotation(_dir);
|
||||
return Vector3.Dot(transform.forward, _dir) > 0 && fov > Quaternion.Angle(transform.rotation, dir);
|
||||
}
|
||||
|
||||
private bool CheckSight(ref Collider _collider)
|
||||
{
|
||||
if (!requireSight) return false;
|
||||
var transform1 = _collider.transform;
|
||||
var position = transform1.position;
|
||||
var position = _collider.bounds.center;
|
||||
//是检测bounds的顶部
|
||||
position.y += _collider.bounds.extents.y;
|
||||
var location = new Location(Transform);
|
||||
var length = Physics.RaycastNonAlloc(
|
||||
location.position,
|
||||
@@ -82,23 +87,32 @@ namespace BITKit.Sensors
|
||||
Vector3.Distance(location, position),
|
||||
blockLayer
|
||||
);
|
||||
|
||||
switch (length)
|
||||
{
|
||||
case 0:
|
||||
Debug.DrawLine(location, position, Color.green, 1);
|
||||
return true;
|
||||
case 1:
|
||||
if (hits[0].collider == _collider)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (hits.Take(length).Any(x => ignoreColliders.Contains(x.collider) is false))
|
||||
return hits[0].collider == _collider;
|
||||
default:
|
||||
var collider1 = _collider;
|
||||
if (hits.Take(length).Any(Predicate))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
bool Predicate(RaycastHit x)
|
||||
{
|
||||
var result = ignoreColliders.Contains(x.collider) is false && x.collider != collider1;
|
||||
if (result)
|
||||
{
|
||||
Debug.DrawLine(location, x.point, Color.red, 1);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user