Files
zeling_v2/Assets/_Game/Scripts/Enemies/EnemyDebugOverlay.cs
Joywayer a1b4e629aa feat: Implement Room Streaming System
- Add RoomStreamingManager to manage room loading and unloading based on player proximity.
- Create StreamingBudgetConfigSO for memory and performance budgeting of the streaming system.
- Introduce TransitionDirector to handle seamless and atmospheric fade transitions between rooms.
- Develop WorldGraph to represent room connectivity and facilitate neighbor queries and distance calculations.
- Implement RoomNode and RoomEdge classes to structure room data and connections.
2026-05-23 19:10:29 +08:00

150 lines
5.6 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#if UNITY_EDITOR || DEVELOPMENT_BUILD
using UnityEngine;
using BaseGames.Enemies.Abilities;
using BaseGames.Enemies.StatusEffects;
namespace BaseGames.Enemies
{
/// <summary>
/// 运行时 AI 状态调试叠加层(仅 Editor
/// 挂到敌人 Prefab 根节点,运行时在场景视图 / GameView 上显示:
/// - AiPhase / EnemyStateType
/// - 当前激活的能力名称及运行状态
/// - LOS 状态 / 到玩家距离
/// - Boss技能执行状态 + 各技能冷却倒计时
/// </summary>
[AddComponentMenu("BaseGames/Debug/Enemy Debug Overlay")]
public sealed class EnemyDebugOverlay : MonoBehaviour
{
[Header("显示选项")]
[Tooltip("在 Scene 视图中绘制 GUI 标签")]
[SerializeField] private bool _showInSceneView = true;
[Tooltip("在 Game 视图中绘制 GUI 标签(需要 OnGUI")]
[SerializeField] private bool _showInGameView = false;
[Tooltip("文字背景透明度")]
[SerializeField, Range(0f, 1f)] private float _bgAlpha = 0.65f;
private EnemyBase _enemy;
private BossBase _boss;
private EnemyStatusEffectManager _statusMgr;
private GUIStyle _labelStyle;
private GUIStyle _boxStyle;
private bool _stylesInit;
private void Awake()
{
_enemy = GetComponent<EnemyBase>();
_boss = GetComponent<BossBase>();
_statusMgr = GetComponent<EnemyStatusEffectManager>();
}
// ── Scene 视图标签UnityEditor.Handles.Label─────────────────────
private void OnDrawGizmos()
{
if (!_showInSceneView || !Application.isPlaying || _enemy == null) return;
var lines = BuildLines();
var label = string.Join("\n", lines);
var pos = transform.position + Vector3.up * 2.2f;
UnityEditor.Handles.Label(pos, label);
}
// ── Game 视图 GUIOnGUI──────────────────────────────────────────
private void OnGUI()
{
if (!_showInGameView || !Application.isPlaying || _enemy == null) return;
InitStyles();
var cam = UnityEngine.Camera.main;
if (cam == null) return;
Vector3 worldPos = transform.position + Vector3.up * 2.2f;
Vector3 screen = cam.WorldToScreenPoint(worldPos);
if (screen.z < 0f) return;
float screenY = Screen.height - screen.y;
var lines = BuildLines();
var text = string.Join("\n", lines);
var size = _labelStyle.CalcSize(new GUIContent(text));
var rect = new Rect(screen.x - size.x * 0.5f, screenY - size.y, size.x + 8f, size.y + 4f);
GUI.Box(rect, GUIContent.none, _boxStyle);
GUI.Label(rect, text, _labelStyle);
}
// ── 内部 ──────────────────────────────────────────────────────────
private System.Collections.Generic.List<string> BuildLines()
{
var list = new System.Collections.Generic.List<string>(8);
// 名称
list.Add($"<b>{gameObject.name}</b>");
// AiPhase + EnemyState
list.Add($"Phase: <color=#ffcc44>{_enemy.CurrentAiPhase}</color> State: <color=#88ddff>{_enemy.CurrentState}</color>");
// 距离 + LOS
float dist = _enemy.Stats != null ? Mathf.Sqrt(_enemy.Stats.SqrDistanceToPlayer) : -1f;
bool los = _enemy.IsPlayerVisible();
var losColor = los ? "#44ff88" : "#ff6644";
list.Add($"Dist: {dist:F1}m LOS: <color={losColor}>{los}</color>");
// 当前激活能力
if (_enemy.Abilities != null)
{
foreach (var ab in _enemy.Abilities.All)
{
if (ab.IsRunning)
{
string abilityId = ab.Config?.abilityId ?? ab.GetType().Name;
list.Add($"Ability: <color=#ffaa44>{abilityId}</color> [{ab.Phase}]");
}
}
}
// Boss 信息
if (_boss != null)
{
list.Add($"BossSkillExec: <color={( _boss.IsBossSkillExecuting ? "#ff4444" : "#aaaaaa")}>{_boss.IsBossSkillExecuting}</color>");
}
// 状态效果
if (_statusMgr != null)
{
var effects = _statusMgr.ActiveEffects;
for (int i = 0; i < effects.Count; i++)
list.Add($"FX: <color=#dd88ff>{effects[i].Type}</color>");
}
return list;
}
private void InitStyles()
{
if (_stylesInit) return;
_stylesInit = true;
_labelStyle = new GUIStyle(GUI.skin.label)
{
richText = true,
fontSize = 11,
alignment = TextAnchor.UpperLeft,
padding = new RectOffset(4, 4, 2, 2),
};
_labelStyle.normal.textColor = Color.white;
var bgTex = new Texture2D(1, 1);
bgTex.SetPixel(0, 0, new Color(0.05f, 0.05f, 0.1f, _bgAlpha));
bgTex.Apply();
_boxStyle = new GUIStyle(GUI.skin.box);
_boxStyle.normal.background = bgTex;
}
}
}
#endif