using UnityEngine; #if UNITY_EDITOR using UnityEditor; #endif /// /// Helper script to visualize puck-related debug information in the scene /// Attach this to any GameObject to see possession ranges, puck trajectory, etc. /// public class PuckDebugVisualizer : MonoBehaviour { [Header("Visualization Settings")] [SerializeField] private bool showPossessionRanges = true; [SerializeField] private bool showPuckTrajectory = true; [SerializeField] private bool showPlayerLabels = true; [SerializeField] private float trajectoryTime = 2.0f; [Header("Colors")] [SerializeField] private Color possessionRangeColor = new Color(1f, 1f, 0f, 0.3f); [SerializeField] private Color hasPuckColor = new Color(0f, 1f, 0f, 0.5f); [SerializeField] private Color noPuckColor = new Color(1f, 0f, 0f, 0.3f); private PuckController puck; private PlayerController[] allPlayers; void Start() { puck = FindObjectOfType(); allPlayers = FindObjectsOfType(); } #if UNITY_EDITOR void OnDrawGizmos() { if (!Application.isPlaying) { puck = FindObjectOfType(); allPlayers = FindObjectsOfType(); } if (showPossessionRanges && allPlayers != null) { DrawPossessionRanges(); } if (showPuckTrajectory && puck != null) { DrawPuckTrajectory(); } } void DrawPossessionRanges() { foreach (PlayerController player in allPlayers) { if (player == null) continue; // Choose color based on possession bool hasPuck = player.HasPuck(); Gizmos.color = hasPuck ? hasPuckColor : possessionRangeColor; // Draw sphere showing pickup range Gizmos.DrawWireSphere(player.transform.position, 1.5f); // Draw label if (showPlayerLabels && player.stats != null) { Vector3 labelPos = player.transform.position + Vector3.up * 2f; string label = $"{player.stats.playerName}\n{player.stats.position}"; if (hasPuck) label += "\n[HAS PUCK]"; Handles.Label(labelPos, label); } } } void DrawPuckTrajectory() { if (puck == null) return; // Draw current puck position Gizmos.color = Color.yellow; Gizmos.DrawWireSphere(puck.transform.position, 0.15f); // If puck is moving, draw predicted trajectory Vector3 velocity = puck.GetVelocity(); if (velocity.magnitude > 0.1f) { Gizmos.color = Color.cyan; Vector3 currentPos = puck.transform.position; float timeStep = 0.1f; for (float t = 0; t < trajectoryTime; t += timeStep) { Vector3 nextPos = currentPos + velocity * timeStep; Gizmos.DrawLine(currentPos, nextPos); currentPos = nextPos; // Approximate drag velocity *= 0.98f; } // Draw end point Gizmos.DrawWireSphere(currentPos, 0.1f); } // Draw line to current carrier if (puck.CurrentCarrier != null) { Gizmos.color = Color.green; Gizmos.DrawLine(puck.transform.position, puck.CurrentCarrier.transform.position); } } #endif // Runtime debug GUI void OnGUI() { if (!Application.isPlaying) return; GUILayout.BeginArea(new Rect(10, 10, 300, 400)); GUILayout.BeginVertical("box"); GUILayout.Label("Puck Debug Info", new GUIStyle(GUI.skin.label) { richText = true, fontSize = 14 }); if (puck != null) { GUILayout.Label($"Puck Position: {puck.transform.position}"); GUILayout.Label($"Puck Velocity: {puck.GetVelocity().magnitude:F2} m/s"); GUILayout.Label($"Puck Speed: {puck.GetSpeed():F2} m/s"); if (puck.IsLoose) { GUILayout.Label("Puck Status: LOOSE", new GUIStyle(GUI.skin.label) { richText = true }); } else if (puck.CurrentCarrier != null) { GUILayout.Label($"Carried by: {puck.CurrentCarrier.stats.playerName}", new GUIStyle(GUI.skin.label) { richText = true }); } } GUILayout.Space(10); GUILayout.Label("Players with Puck", new GUIStyle(GUI.skin.label) { richText = true }); if (allPlayers != null) { foreach (PlayerController player in allPlayers) { if (player != null && player.HasPuck()) { GUILayout.Label($"• {player.stats.playerName} ({player.stats.position})"); } } } GUILayout.Space(10); // Test buttons if (GUILayout.Button("Trigger Faceoff (F)")) { FaceoffManager manager = FindObjectOfType(); if (manager != null) { manager.StartFaceoff(); } } if (puck != null && puck.CurrentCarrier != null) { if (GUILayout.Button("Release Puck")) { puck.Release(); } } GUILayout.EndVertical(); GUILayout.EndArea(); } }