- Updated PhysicsPerceptionSystem to support seven detection modes: RangeCircle, BatchLOS, FanCast, BoxCast, Sight, RayCast, and TriggerZone. - Improved documentation for each detection mode, including performance optimization strategies. - Introduced PerceptionTriggerProxy for event-driven detection in TriggerZone slots. - Added SightBatchSystem to manage Sight slots efficiently, reducing CPU spikes during high enemy counts. - Updated SensorSlotNames to reflect new detection modes and their purposes. - Enhanced internal logic for detecting targets and managing detection events.
58 lines
2.8 KiB
C#
58 lines
2.8 KiB
C#
using UnityEngine;
|
||
|
||
namespace BaseGames.Enemies.Perception
|
||
{
|
||
/// <summary>
|
||
/// 挂载在 PhysicsPerceptionSystem 子节点上的触发器代理组件。
|
||
/// 与 <see cref="PhysicsPerceptionSystem"/> 的 <c>TriggerZone</c> 槽位配合使用:
|
||
/// 当物理触发器产生 Enter / Exit 事件时,通知父系统的感知字典,
|
||
/// 同时触发 <see cref="PhysicsPerceptionSystem.OnEnterDetection"/> /
|
||
/// <see cref="PhysicsPerceptionSystem.OnExitDetection"/> 委托。
|
||
///
|
||
/// <b>使用步骤:</b>
|
||
/// 1. 在 PhysicsPerceptionSystem 的子 GameObject 上添加本组件。
|
||
/// 2. 确保同一 GameObject 或子节点上有 Collider2D,且 <c>isTrigger = true</c>。
|
||
/// 3. 填写 <see cref="slotName"/>(与父系统中同名 TriggerZone 槽位对应)。
|
||
/// 4. 设置 <see cref="detectLayer"/>(只有命中该层的碰撞体才会触发通知)。
|
||
/// 5. <see cref="ParentSystem"/> 由父系统 Awake() 自动赋值,无需手动操作。
|
||
/// </summary>
|
||
[AddComponentMenu("BaseGames/Enemies/Perception Trigger Proxy")]
|
||
[RequireComponent(typeof(Collider2D))]
|
||
public sealed class PerceptionTriggerProxy : MonoBehaviour
|
||
{
|
||
[Tooltip("对应 PhysicsPerceptionSystem 中 TriggerZone 槽位的 slotName")]
|
||
public string slotName;
|
||
|
||
[Tooltip("目标检测层,只有命中此层的碰撞体才通知父系统")]
|
||
public LayerMask detectLayer;
|
||
|
||
/// <summary>由父 PhysicsPerceptionSystem 在 Awake() 中自动注入,无需手动赋值。</summary>
|
||
internal PhysicsPerceptionSystem ParentSystem { get; set; }
|
||
|
||
// ── Unity 生命周期 ────────────────────────────────────────────────────
|
||
|
||
private void OnValidate()
|
||
{
|
||
var col = GetComponent<Collider2D>();
|
||
if (col != null && !col.isTrigger)
|
||
Debug.LogWarning(
|
||
$"[PerceptionTriggerProxy] '{name}' 上的 Collider2D.isTrigger 未勾选," +
|
||
"TriggerZone 槽位将无法工作。", this);
|
||
}
|
||
|
||
private void OnTriggerEnter2D(Collider2D other)
|
||
{
|
||
if (ParentSystem == null || string.IsNullOrEmpty(slotName)) return;
|
||
if (detectLayer != 0 && ((1 << other.gameObject.layer) & (int)detectLayer) == 0) return;
|
||
ParentSystem.OnTriggerZoneEnter(slotName, other.gameObject);
|
||
}
|
||
|
||
private void OnTriggerExit2D(Collider2D other)
|
||
{
|
||
if (ParentSystem == null || string.IsNullOrEmpty(slotName)) return;
|
||
if (detectLayer != 0 && ((1 << other.gameObject.layer) & (int)detectLayer) == 0) return;
|
||
ParentSystem.OnTriggerZoneExit(slotName, other.gameObject);
|
||
}
|
||
}
|
||
}
|