2023-07-02 02:20:40 +08:00
|
|
|
using System;
|
2023-06-29 14:57:11 +08:00
|
|
|
using System.Collections.Generic;
|
|
|
|
using System.Linq;
|
|
|
|
using Cysharp.Threading.Tasks;
|
|
|
|
using UnityEngine;
|
|
|
|
using UnityEngine.Events;
|
2023-07-02 02:20:40 +08:00
|
|
|
using UnityEngine.UIElements;
|
|
|
|
#if UNITY_EDITOR
|
|
|
|
using UnityEditor;
|
|
|
|
using UnityEditor.UIElements;
|
|
|
|
#endif
|
2023-06-29 14:57:11 +08:00
|
|
|
namespace BITKit.Sensors
|
|
|
|
{
|
|
|
|
public class TriggerSensor : MonoBehaviour, ISensor
|
|
|
|
{
|
|
|
|
[Header(Constant.Header.Settings)] [SerializeField]
|
|
|
|
private List<GameObject> ignores = new();
|
|
|
|
|
2023-07-02 02:20:40 +08:00
|
|
|
[SerializeField] private Optional<LayerMask> detectedLayer;
|
|
|
|
[SerializeField] private bool allowStatic;
|
2023-07-05 10:20:36 +08:00
|
|
|
[SerializeField] private bool useRigidbody;
|
2023-07-02 02:20:40 +08:00
|
|
|
|
2023-06-29 14:57:11 +08:00
|
|
|
[Header(Constant.Header.Events)] public UnityEvent<Collider> onDetected = new();
|
|
|
|
public UnityEvent<Collider> onLost = new();
|
|
|
|
|
|
|
|
[Header(Constant.Header.InternalVariables)]
|
|
|
|
// ReSharper disable once FieldCanBeMadeReadOnly.Local
|
|
|
|
private List<Collider> detected = new();
|
2023-07-02 02:20:40 +08:00
|
|
|
|
2023-07-17 10:23:47 +08:00
|
|
|
private readonly Queue<Collider> triggerEnterQueue=new();
|
|
|
|
private readonly Queue<Collider> triggerExitQueue=new();
|
2023-07-02 02:20:40 +08:00
|
|
|
|
2023-06-29 14:57:11 +08:00
|
|
|
private void OnTriggerEnter(Collider _collider)
|
|
|
|
{
|
2023-07-02 02:20:40 +08:00
|
|
|
triggerEnterQueue.Enqueue(_collider);
|
2023-06-29 14:57:11 +08:00
|
|
|
}
|
|
|
|
private void OnTriggerExit(Collider _collider)
|
|
|
|
{
|
2023-07-02 02:20:40 +08:00
|
|
|
triggerExitQueue.Enqueue(_collider);
|
2023-06-29 14:57:11 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
private void OnCollisionEnter(Collision collision)
|
|
|
|
{
|
|
|
|
var _collider = collision.collider;
|
|
|
|
if (!IsValid(_collider)) return;
|
|
|
|
detected.Add(_collider);
|
|
|
|
onDetected.Invoke(_collider);
|
|
|
|
}
|
|
|
|
|
|
|
|
private void OnCollisionStay(Collision collision)
|
|
|
|
{
|
|
|
|
var _collider = collision.collider;
|
|
|
|
if (detected.TryRemove(_collider))
|
|
|
|
{
|
|
|
|
onLost.Invoke(_collider);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public IEnumerable<Transform> Get() => detected.Select(x => x.transform).ToArray();
|
|
|
|
|
2023-07-02 02:20:40 +08:00
|
|
|
//public bool IsValid(Collider _collider) => ignores.Contains(_collider.gameObject) is false;
|
|
|
|
public bool IsValid(Collider _collider)
|
|
|
|
{
|
|
|
|
if(allowStatic is false && _collider.gameObject.isStatic) return false;
|
2023-08-11 23:57:37 +08:00
|
|
|
var attachedRigidbody = _collider.attachedRigidbody;
|
|
|
|
var detectedObject = _collider switch
|
|
|
|
{
|
|
|
|
var x when attachedRigidbody is not null && useRigidbody => attachedRigidbody.gameObject,
|
|
|
|
_ => _collider.gameObject,
|
|
|
|
};
|
|
|
|
if (ignores.Contains(detectedObject)) return false;
|
2023-07-02 02:20:40 +08:00
|
|
|
return !detectedLayer.Allow || detectedLayer.Value.Includes(_collider.gameObject.layer);
|
|
|
|
}
|
2023-06-29 14:57:11 +08:00
|
|
|
|
|
|
|
public float GetDistance()
|
|
|
|
{
|
2023-08-11 23:57:37 +08:00
|
|
|
throw new NotImplementedException();
|
2023-06-29 14:57:11 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
public UniTask Execute()
|
|
|
|
{
|
2023-08-11 23:57:37 +08:00
|
|
|
throw new NotImplementedException();
|
2023-06-29 14:57:11 +08:00
|
|
|
}
|
2023-07-02 02:20:40 +08:00
|
|
|
|
|
|
|
private void Update()
|
|
|
|
{
|
|
|
|
while (triggerEnterQueue.TryDequeue(out var _collider))
|
|
|
|
{
|
|
|
|
if (IsValid(_collider) is false) return;
|
|
|
|
if (triggerExitQueue.Contains(_collider) || detected.Contains(_collider))continue;
|
|
|
|
detected.Add(_collider);
|
|
|
|
}
|
|
|
|
while (triggerExitQueue.TryDequeue(out var _collider))
|
|
|
|
{
|
|
|
|
if (IsValid(_collider) is false) return;
|
|
|
|
detected.Remove(_collider);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#if UNITY_EDITOR
|
2023-07-17 10:23:47 +08:00
|
|
|
[CustomEditor(typeof(Sensor),true)]
|
|
|
|
public class SensorInspector:BITInspector<Sensor>
|
|
|
|
{
|
|
|
|
private VisualElement detectedContainer;
|
|
|
|
public override VisualElement CreateInspectorGUI()
|
|
|
|
{
|
|
|
|
FillDefaultInspector();
|
|
|
|
|
|
|
|
detectedContainer = root.Create<VisualElement>();
|
|
|
|
|
|
|
|
return root;
|
|
|
|
}
|
|
|
|
protected override void OnUpdate()
|
|
|
|
{
|
|
|
|
if (detectedContainer is null) return;
|
|
|
|
detectedContainer.Clear();
|
|
|
|
foreach (var x in agent.Get())
|
|
|
|
{
|
|
|
|
|
|
|
|
ObjectField objectField = new()
|
|
|
|
{
|
|
|
|
objectType = x.GetType(),
|
|
|
|
value = x,
|
|
|
|
};
|
|
|
|
objectField.SetEnabled(false);
|
|
|
|
detectedContainer.Add(objectField);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
[CustomEditor(typeof(TriggerSensor),true)]
|
2023-07-02 02:20:40 +08:00
|
|
|
public class TriggerSensorInspector:BITInspector<TriggerSensor>
|
|
|
|
{
|
|
|
|
private VisualElement detectedContainer;
|
|
|
|
public override VisualElement CreateInspectorGUI()
|
|
|
|
{
|
|
|
|
FillDefaultInspector();
|
|
|
|
|
|
|
|
detectedContainer = root.Create<VisualElement>();
|
|
|
|
|
|
|
|
return root;
|
|
|
|
}
|
|
|
|
protected override void OnUpdate()
|
|
|
|
{
|
|
|
|
if (detectedContainer is null) return;
|
|
|
|
detectedContainer.Clear();
|
|
|
|
foreach (var x in agent.Get())
|
|
|
|
{
|
|
|
|
|
|
|
|
ObjectField objectField = new()
|
|
|
|
{
|
|
|
|
objectType = x.GetType(),
|
|
|
|
value = x,
|
|
|
|
};
|
|
|
|
objectField.SetEnabled(false);
|
|
|
|
detectedContainer.Add(objectField);
|
|
|
|
}
|
|
|
|
}
|
2023-06-29 14:57:11 +08:00
|
|
|
}
|
2023-07-02 02:20:40 +08:00
|
|
|
#endif
|
2023-06-29 14:57:11 +08:00
|
|
|
}
|