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();
}
}