feat: Enhance Physics Perception System with new detection modes and performance optimizations

- 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.
This commit is contained in:
2026-06-02 23:18:20 +08:00
parent 150440495d
commit d27ae9407d
17 changed files with 1946 additions and 335 deletions

View File

@@ -0,0 +1,57 @@
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);
}
}
}