1
This commit is contained in:
@@ -1,49 +1,49 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Pool;
|
||||
using System.Linq;
|
||||
using UnityEditor.Search;
|
||||
|
||||
namespace BITKit.Sensors
|
||||
{
|
||||
public interface IAudioObject
|
||||
{
|
||||
float GetVolume();
|
||||
}
|
||||
public class AudioSensor : Sensor
|
||||
public class AudioSensor : MonoBehaviour,ISensor
|
||||
{
|
||||
[Header(Constant.Header.Settings)]
|
||||
public float radius;
|
||||
[Header(Constant.Header.InternalVariables)]
|
||||
IAudioObject currentAudioObject;
|
||||
Collider currentCollider;
|
||||
Collider[] colliders = new Collider[32];
|
||||
public override IEnumerable<Transform> Get() => detected;
|
||||
public override UniTask Execute()
|
||||
[SerializeField] private bool autoUpdate;
|
||||
[SerializeField]private float radius;
|
||||
private readonly CacheList<Transform> cache = new();
|
||||
private void OnEnable()
|
||||
{
|
||||
var cacheList = ListPool<Transform>.Get();
|
||||
for (int i = 0; i < Physics.OverlapSphereNonAlloc(transform.position, radius, colliders, detectLayer); i++)
|
||||
Id = GetInstanceID();
|
||||
SensorQueue.Register(Id,this);
|
||||
}
|
||||
private void OnDisable()
|
||||
{
|
||||
SensorQueue.UnRegister(Id);
|
||||
}
|
||||
public UniTask Execute(float delta)
|
||||
{
|
||||
var position = transform.position;
|
||||
cache.Clear();
|
||||
foreach (var x in AudioSensorService.QuadtreeRoot.Find(new Bounds(position, Vector3.one * radius)))
|
||||
{
|
||||
currentCollider = colliders[i];
|
||||
if (IsValid(currentCollider))
|
||||
{
|
||||
cacheList.Add(currentCollider.transform);
|
||||
}
|
||||
var distance = Vector3.Distance(position, x.Position);
|
||||
if(distance>radius) continue;
|
||||
cache.Add(x.Transform);
|
||||
}
|
||||
detected = cacheList.ToArray();
|
||||
ListPool<Transform>.Release(cacheList);
|
||||
return UniTask.CompletedTask;
|
||||
}
|
||||
public override bool IsValid(Collider _collider)
|
||||
{
|
||||
if (ignoreColliders.Contains(_collider) is false)
|
||||
if (Vector3.Distance(transform.position, _collider.transform.position) <= radius)
|
||||
if (_collider.TryGetComponent<IAudioObject>(out currentAudioObject))
|
||||
{
|
||||
return currentAudioObject.GetVolume() >= 1;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public override float GetDistance() => radius;
|
||||
public int Id { get; set; }
|
||||
public IEnumerable<Transform> Get() => cache.ValueArray;
|
||||
public bool IsValid(Collider _collider) => false;
|
||||
public float GetDistance() => radius;
|
||||
public bool AutoUpdate=>autoUpdate;
|
||||
}
|
||||
}
|
67
Assets/BITKit/Unity/Scripts/Sensor/AudioSensorService.cs
Normal file
67
Assets/BITKit/Unity/Scripts/Sensor/AudioSensorService.cs
Normal file
@@ -0,0 +1,67 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using kcp2k;
|
||||
using Quadtree;
|
||||
using Quadtree.Items;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Pool;
|
||||
|
||||
namespace BITKit.Sensors
|
||||
{
|
||||
public class AudioSensorService : MonoBehaviour
|
||||
{
|
||||
public class AudioSensorData:IItem<AudioSensorData,Node<AudioSensorData>>
|
||||
{
|
||||
public int Id;
|
||||
public Vector3 Position;
|
||||
public float Radius;
|
||||
public Transform Transform;
|
||||
public Bounds Bounds;
|
||||
public ITag Tag;
|
||||
public Bounds GetBounds() => Bounds;
|
||||
public Node<AudioSensorData> ParentNode { get; set; }
|
||||
public void QuadTree_Root_Initialized(IQuadtreeRoot<AudioSensorData, Node<AudioSensorData>> root){}
|
||||
}
|
||||
internal static readonly QuadtreeRoot<AudioSensorData, Node<AudioSensorData>> QuadtreeRoot =
|
||||
new(default, Vector3.one * 2048);
|
||||
|
||||
private static Pool<AudioSensorData> pool = new(()=>new(), x=>{}, 1000);
|
||||
private static int count;
|
||||
public static async void MakeNoise(Vector3 position,Transform transform)
|
||||
{
|
||||
var data = pool.Take();
|
||||
data.Id = count++;
|
||||
data.Position = position;
|
||||
data.Transform = transform;
|
||||
data.Bounds = new Bounds(position, Vector3.one *1);
|
||||
data.Tag = transform.GetComponent<ITag>();
|
||||
QuadtreeRoot.Insert(data);
|
||||
await UniTask.Delay(3000);
|
||||
if (disposed) return;
|
||||
QuadtreeRoot.Remove(data);
|
||||
pool.Return(data);
|
||||
}
|
||||
private static bool disposed;
|
||||
[SerializeReference, SubclassSelector] private ITicker ticker;
|
||||
private void Start()
|
||||
{
|
||||
disposed = false;
|
||||
ticker.Add(OnTick);
|
||||
destroyCancellationToken.Register(Dispose);
|
||||
pool.Clear();
|
||||
}
|
||||
private void Dispose()
|
||||
{
|
||||
ticker.Remove(OnTick);
|
||||
disposed = true;
|
||||
QuadtreeRoot.Clear();
|
||||
}
|
||||
private void OnTick(float obj)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@@ -9,7 +9,8 @@
|
||||
"GUID:f51ebe6a0ceec4240a699833d6309b23",
|
||||
"GUID:be17a8778dbfe454890ed8279279e153",
|
||||
"GUID:14fe60d984bf9f84eac55c6ea033a8f4",
|
||||
"GUID:9400d40641bab5b4a9702f65bf5c6eb5"
|
||||
"GUID:9400d40641bab5b4a9702f65bf5c6eb5",
|
||||
"GUID:1193c2664d97cc049a6e4c486c6bce71"
|
||||
],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
|
@@ -17,6 +17,7 @@ namespace BITKit.Sensors
|
||||
/// </summary>
|
||||
public interface ISensor
|
||||
{
|
||||
int Id { get; }
|
||||
/// <summary>
|
||||
/// 自动更新
|
||||
/// </summary>
|
||||
@@ -45,7 +46,7 @@ namespace BITKit.Sensors
|
||||
/// 传感器执行检测
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
UniTask Execute();
|
||||
UniTask Execute(float delta);
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
@@ -53,6 +54,8 @@ namespace BITKit.Sensors
|
||||
{
|
||||
[SerializeField] private GameObject gameObject;
|
||||
private ISensor _sensorImplementation => gameObject.GetComponent<ISensor>();
|
||||
public int Id => _sensorImplementation.Id;
|
||||
|
||||
public IEnumerable<Transform> Get()
|
||||
{
|
||||
return _sensorImplementation.Get();
|
||||
@@ -67,10 +70,9 @@ namespace BITKit.Sensors
|
||||
{
|
||||
return _sensorImplementation.GetDistance();
|
||||
}
|
||||
|
||||
public UniTask Execute()
|
||||
public UniTask Execute(float delta)
|
||||
{
|
||||
return _sensorImplementation.Execute();
|
||||
return _sensorImplementation.Execute(delta);
|
||||
}
|
||||
}
|
||||
[System.Serializable]
|
||||
@@ -78,6 +80,8 @@ namespace BITKit.Sensors
|
||||
{
|
||||
[SerializeField] private MonoBehaviour monoBehaviour;
|
||||
private ISensor _sensorImplementation=>monoBehaviour as ISensor;
|
||||
public int Id => _sensorImplementation.Id;
|
||||
|
||||
public IEnumerable<Transform> Get()
|
||||
{
|
||||
return _sensorImplementation.Get();
|
||||
@@ -93,9 +97,9 @@ namespace BITKit.Sensors
|
||||
return _sensorImplementation.GetDistance();
|
||||
}
|
||||
|
||||
public UniTask Execute()
|
||||
public UniTask Execute(float delta)
|
||||
{
|
||||
return _sensorImplementation.Execute();
|
||||
return _sensorImplementation.Execute(delta);
|
||||
}
|
||||
}
|
||||
public abstract class Sensor : MonoBehaviour, ISensor
|
||||
@@ -106,16 +110,15 @@ namespace BITKit.Sensors
|
||||
[Header(Constant.Header.Gameobjects)]
|
||||
public Collider[] ignoreColliders;
|
||||
[Header(Constant.Header.InternalVariables)]
|
||||
[NonSerialized]
|
||||
[SerializeField,ReadOnly]
|
||||
public Transform[] detected = Array.Empty<Transform>();
|
||||
public abstract IEnumerable<Transform> Get();
|
||||
public abstract bool IsValid(Collider _collider);
|
||||
public abstract UniTask Execute();
|
||||
public abstract float GetDistance();
|
||||
|
||||
public virtual UniTask Execute(float delta)=>UniTask.CompletedTask;
|
||||
public int Id { get; private set; }
|
||||
bool ISensor.AutoUpdate => autoUpdate;
|
||||
|
||||
protected int Id;
|
||||
protected Transform Transform;
|
||||
|
||||
protected virtual void OnEnable()
|
||||
|
16
Assets/BITKit/Unity/Scripts/Sensor/Core/SensorTarget.cs
Normal file
16
Assets/BITKit/Unity/Scripts/Sensor/Core/SensorTarget.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace BITKit.Sensors
|
||||
{
|
||||
public interface ISensorTarget
|
||||
{
|
||||
public int Id { get; }
|
||||
Bounds Bounds { get; }
|
||||
Transform Transform { get; }
|
||||
void Detected(float weight,ISensor sensor,object sender);
|
||||
event Action<float, ISensor, object> OnDetected;
|
||||
}
|
||||
}
|
@@ -12,7 +12,7 @@ namespace BITKit.Sensors
|
||||
public override IEnumerable<Transform> Get()=>sensors.SelectMany(x => x.Get());
|
||||
public override bool IsValid(Collider _collider) => sensors.Any(x => x.IsValid(_collider) is false) is false;
|
||||
public override float GetDistance() => sensors.Min(x => x.GetDistance());
|
||||
public override UniTask Execute() => UniTask.WhenAll(sensors.Select(x => x.Execute()));
|
||||
public override UniTask Execute(float delta) => UniTask.WhenAll(sensors.Select(x => x.Execute(delta)));
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -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;
|
||||
}
|
||||
}
|
||||
|
@@ -13,7 +13,7 @@ namespace BITKit.Sensors
|
||||
public float distance;
|
||||
public override IEnumerable<Transform> Get() => detected;
|
||||
private readonly RaycastHit[] raycasts = new RaycastHit[16];
|
||||
public override UniTask Execute()
|
||||
public override UniTask Execute(float delta)
|
||||
{
|
||||
var _transform = transform;
|
||||
var forward = _transform.forward;
|
||||
@@ -46,7 +46,7 @@ namespace BITKit.Sensors
|
||||
{
|
||||
if (autoUpdate)
|
||||
{
|
||||
Execute().Forget();
|
||||
Execute(Time.deltaTime).Forget();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Cysharp.Threading.Tasks;
|
||||
@@ -10,6 +11,7 @@ namespace BITKit.Sensors
|
||||
public class SensorQueue : MonoBehaviour
|
||||
{
|
||||
internal static readonly Dictionary<int,ISensor> Sensors=new();
|
||||
internal static readonly ConcurrentDictionary<int, float> LastDetectedTime = new();
|
||||
private static bool IsDirty;
|
||||
|
||||
[SerializeField,ReadOnly] private int _position;
|
||||
@@ -32,10 +34,25 @@ namespace BITKit.Sensors
|
||||
}
|
||||
|
||||
[SerializeField] private MonoBehaviour[] sensors;
|
||||
|
||||
private void Update()
|
||||
[SerializeReference,SubclassSelector] private ITicker ticker;
|
||||
|
||||
private bool _isBusy;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
ticker.Add(OnTick);
|
||||
destroyCancellationToken.Register(Dispose);
|
||||
}
|
||||
private void Dispose()
|
||||
{
|
||||
ticker.Remove(OnTick);
|
||||
}
|
||||
private async void OnTick(float obj)
|
||||
{
|
||||
if (_isBusy) return;
|
||||
if (SensorGlobalSettings.Enabled is false) return;
|
||||
|
||||
_isBusy = true;
|
||||
if(IsDirty)
|
||||
{
|
||||
_position = 0;
|
||||
@@ -44,11 +61,25 @@ namespace BITKit.Sensors
|
||||
sensors = Sensors.Values.Where(IsEnabled).OfType<MonoBehaviour>().ToArray();
|
||||
}
|
||||
|
||||
if(Sensors.Count is 0) return;
|
||||
|
||||
Sensors.ElementAt(_position++).Value.Execute().Forget();
|
||||
if (Sensors.Count is 0)
|
||||
{
|
||||
_isBusy = false;
|
||||
return;
|
||||
}
|
||||
|
||||
var current = Sensors.ElementAt(_position++).Value;
|
||||
var currentUpdateTime = LastDetectedTime.GetOrAdd(current.Id,Time.time);
|
||||
await current.Execute(Time.time-currentUpdateTime);
|
||||
float UpdateValueFactory(int key, float old) => Time.time;
|
||||
LastDetectedTime.AddOrUpdate(current.Id,Time.time,UpdateValueFactory);
|
||||
|
||||
if (destroyCancellationToken.IsCancellationRequested) {
|
||||
_isBusy = false;
|
||||
return;
|
||||
}
|
||||
|
||||
_position %= Sensors.Count;
|
||||
_isBusy = false;
|
||||
}
|
||||
private bool IsEnabled(ISensor sensor)
|
||||
{
|
||||
@@ -60,4 +91,4 @@ namespace BITKit.Sensors
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@@ -3,6 +3,8 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using BITKit.Sensors.States;
|
||||
using BITKit.StateMachine;
|
||||
using Cysharp.Threading.Tasks;
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
@@ -16,212 +18,38 @@ using UnityEngine.UIElements;
|
||||
|
||||
namespace BITKit.Sensors
|
||||
{
|
||||
public interface ISmartTargetProperty{}
|
||||
public interface ISmartTargetState:IState{}
|
||||
/// <summary>
|
||||
/// 智能目标传感器,根据条件,智能选择目标
|
||||
/// </summary>
|
||||
public class SmartTargetSensor :MonoBehaviour,ISensor,IAction
|
||||
public class SmartTargetSensor :StateBasedMonoBehaviour<ISmartTargetState>,ISensor
|
||||
{
|
||||
/// <summary>
|
||||
/// 自动更新
|
||||
/// </summary>
|
||||
[Header(Constant.Header.Settings)]
|
||||
[SerializeField] private bool autoUpdate;
|
||||
[SerializeField] private Optional<string[]> ignoreTags;
|
||||
[SerializeField] private Optional<IntervalUpdate> optionalRetargetInterval;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 主传感器
|
||||
/// </summary>
|
||||
[Header(nameof(Sensor))]
|
||||
[SerializeField,SerializeReference,SubclassSelector] private ISensor sensor;
|
||||
|
||||
[Header(Constant.Header.Debug)]
|
||||
[SerializeReference, ReadOnly] private int updateCount;
|
||||
|
||||
public IEnumerable<Transform> Get() =>CurrentTarget is not null ? new[] { CurrentTarget }:Enumerable.Empty<Transform>();
|
||||
|
||||
bool ISensor.AutoUpdate => autoUpdate;
|
||||
|
||||
internal StringBuilder reportBuilder;
|
||||
internal DoubleBuffer<string> report=new();
|
||||
|
||||
public bool IsValid(Collider _collider)
|
||||
{
|
||||
if (!_collider) return false;
|
||||
if (ignoreTags.Allow)
|
||||
{
|
||||
if (_collider.TryGetComponent<ITag>(out var iTags))
|
||||
{
|
||||
var tags = iTags.GetTags();
|
||||
foreach (var x in ignoreTags.Value)
|
||||
{
|
||||
if (tags.Contains(x))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
public float GetDistance() => sensor.GetDistance();
|
||||
public Transform CurrentTarget { get; private set; }
|
||||
private IEnumerable<Transform> detected = ArraySegment<Transform>.Empty;
|
||||
private Vector3 _currentPosition;
|
||||
private int Id;
|
||||
|
||||
private CancellationTokenSource timeoutCancellationTokenSource=new();
|
||||
|
||||
[SerializeField] private float radius;
|
||||
[SerializeField] private RangeSensor rangeSensor;
|
||||
[SerializeField] private AudioSensor audioSensor;
|
||||
public int Id { get; set; }
|
||||
private readonly CacheList<Transform> _detected=new();
|
||||
private void OnEnable()
|
||||
{
|
||||
SensorQueue.Register(Id=GetInstanceID(),this);
|
||||
Id = GetInstanceID();
|
||||
SensorQueue.Register(Id,this);
|
||||
}
|
||||
private void Start()
|
||||
{
|
||||
TransitionState<Idle>();
|
||||
}
|
||||
private void OnDisable()
|
||||
{
|
||||
SensorQueue.UnRegister(Id);
|
||||
}
|
||||
public async UniTask Execute()
|
||||
public IEnumerable<Transform> Get() => _detected.ValueArray;
|
||||
public bool IsValid(Collider _collider) => false;
|
||||
public float GetDistance() => radius;
|
||||
public UniTask Execute(float delta)
|
||||
{
|
||||
try
|
||||
{
|
||||
_currentPosition = transform.position;
|
||||
updateCount++;
|
||||
timeoutCancellationTokenSource?.Cancel();
|
||||
timeoutCancellationTokenSource = new CancellationTokenSource();
|
||||
await sensor.Execute();
|
||||
|
||||
reportBuilder?.AppendLine($"-----BEGIN------{updateCount}");
|
||||
|
||||
Profiler.BeginSample("Release Detected Buffer");
|
||||
var newDetected = sensor.Get();
|
||||
|
||||
if (reportBuilder is not null)
|
||||
{
|
||||
reportBuilder.AppendLine($"Detected:{newDetected.Count()}");
|
||||
foreach (var x in newDetected)
|
||||
{
|
||||
reportBuilder.AppendLine(x.name);
|
||||
}
|
||||
reportBuilder.AppendLine();
|
||||
}
|
||||
Profiler.EndSample();
|
||||
// ReSharper disable once PossibleMultipleEnumeration
|
||||
if (newDetected.Contains(CurrentTarget))
|
||||
{
|
||||
if (optionalRetargetInterval.Allow && optionalRetargetInterval.Value.AllowUpdate)
|
||||
{
|
||||
reportBuilder?.AppendLine("Retarget Interval Catch,Search New Target");
|
||||
}
|
||||
else
|
||||
{
|
||||
reportBuilder?.AppendLine("Current Target Detected,Keep Target");
|
||||
return;
|
||||
}
|
||||
}
|
||||
Profiler.BeginSample("Filter Detected");
|
||||
|
||||
foreach (var x in newDetected.OrderBy(KeySelector))
|
||||
{
|
||||
if(IsValid(x.GetComponent<Collider>()) is false)continue;
|
||||
CurrentTarget = x;
|
||||
reportBuilder?.AppendLine($"New Target:{x.name},Is oder by distance");
|
||||
break;
|
||||
}
|
||||
Profiler.EndSample();
|
||||
|
||||
reportBuilder?.AppendLine($"-----Complete------{updateCount}");
|
||||
|
||||
if(reportBuilder is not null)
|
||||
{
|
||||
report.Release(reportBuilder.ToString());
|
||||
reportBuilder.Clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
report.Clear();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
BIT4Log.LogException(e);
|
||||
}
|
||||
|
||||
}
|
||||
private float KeySelector(Transform x)
|
||||
{
|
||||
var distance = Vector3.Distance(_currentPosition, x.position);
|
||||
reportBuilder?.AppendLine($"Distance:{distance}@{x.name}");
|
||||
return distance;
|
||||
}
|
||||
void IAction.Execute()
|
||||
{
|
||||
Execute().Forget();
|
||||
}
|
||||
#if UNITY_EDITOR
|
||||
private void OnDrawGizmosSelected()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!CurrentTarget) return;
|
||||
Gizmos.DrawLine(transform.position,CurrentTarget.position);
|
||||
}
|
||||
catch (UnassignedReferenceException)
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#if UNITY_EDITOR
|
||||
[CustomEditor(typeof(SmartTargetSensor))]
|
||||
public class SmartTargetSensorInspector:BITInspector<SmartTargetSensor>
|
||||
{
|
||||
private ObjectField _objectField;
|
||||
private Label _reportLabel;
|
||||
public override VisualElement CreateInspectorGUI()
|
||||
{
|
||||
FillDefaultInspector();
|
||||
|
||||
CreateSubTitle("Editor Debug Field");
|
||||
|
||||
_objectField = root.Create<ObjectField>();
|
||||
|
||||
_objectField.objectType = typeof(Transform);
|
||||
|
||||
_objectField.SetEnabled(false);
|
||||
|
||||
_reportLabel = root.Create<Label>();
|
||||
|
||||
_reportLabel.text = "Waiting agent report";
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
protected override void OnEnabled()
|
||||
{
|
||||
base.OnEnabled();
|
||||
agent.reportBuilder = new();
|
||||
}
|
||||
|
||||
protected override void OnDisabled()
|
||||
{
|
||||
base.OnDisabled();
|
||||
agent.reportBuilder = null;
|
||||
}
|
||||
|
||||
protected override void OnUpdate()
|
||||
{
|
||||
if (_objectField is not null)
|
||||
{
|
||||
_objectField.value = agent.CurrentTarget;
|
||||
}
|
||||
|
||||
if (agent.reportBuilder is not null && _reportLabel is not null && agent.report.TryGetRelease(out var value))
|
||||
{
|
||||
_reportLabel.text = value;
|
||||
}
|
||||
CurrentState?.OnStateUpdate(delta);
|
||||
return UniTask.CompletedTask;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@@ -0,0 +1,30 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using BITKit.StateMachine;
|
||||
using UnityEngine;
|
||||
|
||||
namespace BITKit.Sensors.States
|
||||
{
|
||||
public abstract class SmartTargetSensorStates : ISmartTargetState
|
||||
{
|
||||
public bool Enabled { get; set; }
|
||||
public virtual void Initialize()
|
||||
{
|
||||
}
|
||||
public virtual void OnStateEntry(IState old)
|
||||
{
|
||||
}
|
||||
public virtual void OnStateUpdate(float deltaTime)
|
||||
{
|
||||
}
|
||||
public virtual void OnStateExit(IState old, IState newState)
|
||||
{
|
||||
}
|
||||
}
|
||||
[Serializable]
|
||||
public sealed class Idle : SmartTargetSensorStates
|
||||
{
|
||||
|
||||
}
|
||||
}
|
@@ -61,6 +61,8 @@ namespace BITKit.Sensors
|
||||
onLost.Invoke(_collider);
|
||||
}
|
||||
}
|
||||
public int Id => _id is 0 ? _id = GetInstanceID() : _id;
|
||||
private int _id;
|
||||
|
||||
public IEnumerable<Transform> Get()
|
||||
{
|
||||
@@ -89,13 +91,11 @@ namespace BITKit.Sensors
|
||||
if (ignores.Contains(detectedObject)) return false;
|
||||
return !detectedLayer.Allow || detectedLayer.Value.Includes(_collider.gameObject.layer);
|
||||
}
|
||||
|
||||
public float GetDistance()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public UniTask Execute()=>
|
||||
public UniTask Execute(float delta = 0)=>
|
||||
UniTask.CompletedTask;
|
||||
|
||||
private void Update()
|
||||
|
Reference in New Issue
Block a user