using System.Collections.Generic; using UnityEngine; namespace BrewMonster { /// /// Helper class to track and draw gizmos for skill GFX projectiles. /// Draws projectile path from host to target, auto-removes after 10 seconds. /// 用于跟踪和绘制技能GFX弹道辅助线的辅助类。绘制从施法者到目标的弹道路径,10秒后自动移除。 /// public static class SkillGfxGizmoDrawer { /// /// Gizmo data for a single projectile /// 单个弹道的辅助线数据 /// private class GizmoData { public Vector3 startPos; // Host position / 施法者位置 public Vector3 currentPos; // Current projectile position / 当前弹道位置 public Vector3 targetPos; // Target position / 目标位置 public float createTime; // Time when created / 创建时间 public long hostID; // Host ID for identification / 施法者ID public long targetID; // Target ID for identification / 目标ID public GfxMoveMode moveMode; // Movement mode / 移动模式 } private static readonly List m_GizmoList = new List(); private const float GIZMO_LIFETIME = 10.0f; // 10 seconds / 10秒 /// /// Register a projectile for gizmo drawing /// 注册一个弹道用于辅助线绘制 /// public static void RegisterProjectile(long hostID, long targetID, Vector3 startPos, Vector3 targetPos, GfxMoveMode moveMode) { var gizmo = new GizmoData { startPos = startPos, currentPos = startPos, targetPos = targetPos, createTime = Time.time, hostID = hostID, targetID = targetID, moveMode = moveMode }; m_GizmoList.Add(gizmo); } /// /// Update projectile position /// 更新弹道位置 /// public static void UpdateProjectile(long hostID, long targetID, Vector3 currentPos, Vector3 targetPos) { for (int i = m_GizmoList.Count - 1; i >= 0; i--) { var gizmo = m_GizmoList[i]; if (gizmo.hostID == hostID && gizmo.targetID == targetID) { gizmo.currentPos = currentPos; gizmo.targetPos = targetPos; // Update target in case it moves return; } } } /// /// Remove projectile gizmo /// 移除弹道辅助线 /// public static void RemoveProjectile(long hostID, long targetID) { for (int i = m_GizmoList.Count - 1; i >= 0; i--) { var gizmo = m_GizmoList[i]; if (gizmo.hostID == hostID && gizmo.targetID == targetID) { m_GizmoList.RemoveAt(i); return; } } } /// /// Draw all gizmos (called from OnDrawGizmos) /// 绘制所有辅助线(从OnDrawGizmos调用) /// public static void DrawGizmos() { if (m_GizmoList.Count == 0) return; // No gizmos to draw / 没有辅助线要绘制 float currentTime = Time.time; // Remove expired gizmos and draw active ones // 移除过期的辅助线并绘制活动的 for (int i = m_GizmoList.Count - 1; i >= 0; i--) { var gizmo = m_GizmoList[i]; float age = currentTime - gizmo.createTime; // Remove if expired // 如果过期则移除 if (age > GIZMO_LIFETIME) { m_GizmoList.RemoveAt(i); continue; } // Calculate fade alpha (fade out in last 2 seconds) // 计算淡出透明度(最后2秒淡出) float alpha = age > (GIZMO_LIFETIME - 2.0f) ? 1.0f - ((age - (GIZMO_LIFETIME - 2.0f)) / 2.0f) : 1.0f; // Draw projectile path // 绘制弹道路径 Gizmos.color = GetColorForMoveMode(gizmo.moveMode, alpha); // Draw line from start to current position (trail) // 绘制从起点到当前位置的线(轨迹) if (Vector3.Distance(gizmo.startPos, gizmo.currentPos) > 0.01f) { Gizmos.DrawLine(gizmo.startPos, gizmo.currentPos); } // Draw line from current position to target (remaining path) // 绘制从当前位置到目标的线(剩余路径) Gizmos.color = GetColorForMoveMode(gizmo.moveMode, alpha * 0.5f); // Lighter for remaining path if (Vector3.Distance(gizmo.currentPos, gizmo.targetPos) > 0.01f) { Gizmos.DrawLine(gizmo.currentPos, gizmo.targetPos); } // Draw sphere at current position (larger for visibility) // 在当前位置绘制球体(更大以便可见) Gizmos.color = GetColorForMoveMode(gizmo.moveMode, alpha); Gizmos.DrawSphere(gizmo.currentPos, 0.5f); // Increased from 0.2f to 0.5f // Draw wire sphere at target (larger for visibility) // 在目标位置绘制线框球体(更大以便可见) Gizmos.color = GetColorForMoveMode(gizmo.moveMode, alpha * 0.5f); Gizmos.DrawWireSphere(gizmo.targetPos, 0.5f); // Increased from 0.3f to 0.5f // Draw wire sphere at start position // 在起始位置绘制线框球体 Gizmos.color = GetColorForMoveMode(gizmo.moveMode, alpha * 0.3f); Gizmos.DrawWireSphere(gizmo.startPos, 0.3f); } } /// /// Get color for movement mode /// 根据移动模式获取颜色 /// private static Color GetColorForMoveMode(GfxMoveMode mode, float alpha) { Color baseColor; switch (mode) { case GfxMoveMode.enumLinearMove: baseColor = Color.yellow; // Yellow for linear break; case GfxMoveMode.enumOnTarget: baseColor = Color.red; // Red for instant hit break; case GfxMoveMode.enumParabolicMove: baseColor = Color.green; // Green for parabolic break; case GfxMoveMode.enumMissileMove: baseColor = Color.cyan; // Cyan for missile break; default: baseColor = Color.white; break; } baseColor.a = alpha; return baseColor; } /// /// Clear all gizmos /// 清除所有辅助线 /// public static void ClearAll() { m_GizmoList.Clear(); } /// /// Get current gizmo count (for debugging) /// 获取当前辅助线数量(用于调试) /// public static int GetGizmoCount() { return m_GizmoList.Count; } } }