using UnityEngine; /// /// Positions players correctly for faceoff based on their positions /// Handles both center ice and zone faceoffs /// public class FaceoffPositioning : MonoBehaviour { [Header("Faceoff Locations")] [SerializeField] private Transform centerIceFaceoff; [SerializeField] private Transform homeZoneFaceoff; [SerializeField] private Transform awayZoneFaceoff; [Header("Position Offsets")] [SerializeField] private float centerDistance = 0.5f; // Centers from faceoff dot [SerializeField] private float wingDistance = 3.0f; // Wings from center [SerializeField] private float defenseDistance = 5.0f; // Defenders behind [SerializeField] private float wingBackDistance = 1.5f; // Wings back from faceoff public enum FaceoffLocation { CenterIce, HomeZone, AwayZone } /// /// Position all players for a faceoff /// public void PositionPlayersForFaceoff(FaceoffLocation location) { Transform faceoffSpot = GetFaceoffSpot(location); if (faceoffSpot == null) { Debug.LogError("Faceoff spot not set!"); return; } // Find all players PlayerController[] allPlayers = FindObjectsOfType(); foreach (PlayerController player in allPlayers) { bool isHomeTeam = player.CompareTag("HomeTeam"); Vector3 position = CalculateFaceoffPosition( player.stats.position, isHomeTeam, faceoffSpot.position, location ); player.transform.position = position; // Face the faceoff spot Vector3 lookDirection = faceoffSpot.position - position; if (lookDirection.magnitude > 0.1f) { player.transform.rotation = Quaternion.LookRotation(lookDirection); } } Debug.Log($"Players positioned for {location} faceoff"); } private Transform GetFaceoffSpot(FaceoffLocation location) { switch (location) { case FaceoffLocation.CenterIce: return centerIceFaceoff; case FaceoffLocation.HomeZone: return homeZoneFaceoff; case FaceoffLocation.AwayZone: return awayZoneFaceoff; default: return centerIceFaceoff; } } private Vector3 CalculateFaceoffPosition(PlayerPosition position, bool isHomeTeam, Vector3 faceoffSpot, FaceoffLocation location) { // Multiplier for team side (home = -1, away = +1 typically) float teamSide = isHomeTeam ? -1f : 1f; // Defensive zone faceoffs might require different positioning bool isDefensiveFaceoff = (isHomeTeam && location == FaceoffLocation.HomeZone) || (!isHomeTeam && location == FaceoffLocation.AwayZone); Vector3 offset = Vector3.zero; switch (position) { case PlayerPosition.C: // Center // Centers face each other at faceoff offset = new Vector3(0, 0, centerDistance * teamSide); break; case PlayerPosition.LW: // Left Wing // Wing to the left, slightly back offset = new Vector3(-wingDistance, 0, wingBackDistance * teamSide); break; case PlayerPosition.RW: // Right Wing // Wing to the right, slightly back offset = new Vector3(wingDistance, 0, wingBackDistance * teamSide); break; case PlayerPosition.LD: // Left Defense // Defender back and to the left if (isDefensiveFaceoff) { offset = new Vector3(-defenseDistance * 0.7f, 0, -defenseDistance * teamSide); } else { offset = new Vector3(-defenseDistance * 0.7f, 0, -defenseDistance * 0.5f * teamSide); } break; case PlayerPosition.RD: // Right Defense // Defender back and to the right if (isDefensiveFaceoff) { offset = new Vector3(defenseDistance * 0.7f, 0, -defenseDistance * teamSide); } else { offset = new Vector3(defenseDistance * 0.7f, 0, -defenseDistance * 0.5f * teamSide); } break; } return faceoffSpot + offset; } /// /// Setup faceoff spots automatically based on rink dimensions /// Call this if you don't have faceoff spots set up manually /// [ContextMenu("Auto-Create Faceoff Spots")] public void AutoCreateFaceoffSpots() { // Typical NHL rink: 200ft x 85ft = ~61m x 26m // Faceoff circles are 15ft from blue lines, center ice if (centerIceFaceoff == null) { GameObject centerSpot = new GameObject("CenterIceFaceoff"); centerSpot.transform.position = new Vector3(0, 0, 0); centerIceFaceoff = centerSpot.transform; Debug.Log("Created center ice faceoff spot"); } if (homeZoneFaceoff == null) { GameObject homeSpot = new GameObject("HomeZoneFaceoff"); homeSpot.transform.position = new Vector3(0, 0, -20f); // Adjust based on your rink homeZoneFaceoff = homeSpot.transform; Debug.Log("Created home zone faceoff spot"); } if (awayZoneFaceoff == null) { GameObject awaySpot = new GameObject("AwayZoneFaceoff"); awaySpot.transform.position = new Vector3(0, 0, 20f); // Adjust based on your rink awayZoneFaceoff = awaySpot.transform; Debug.Log("Created away zone faceoff spot"); } Debug.Log("Faceoff spots created! Adjust positions in inspector to match your rink"); } // Testing in editor void Update() { if (!Application.isPlaying) return; // Test keys if (Input.GetKeyDown(KeyCode.Alpha1)) { PositionPlayersForFaceoff(FaceoffLocation.CenterIce); } if (Input.GetKeyDown(KeyCode.Alpha2)) { PositionPlayersForFaceoff(FaceoffLocation.HomeZone); } if (Input.GetKeyDown(KeyCode.Alpha3)) { PositionPlayersForFaceoff(FaceoffLocation.AwayZone); } } // Draw faceoff spots in editor void OnDrawGizmos() { if (centerIceFaceoff != null) { Gizmos.color = Color.blue; Gizmos.DrawWireSphere(centerIceFaceoff.position, 0.3f); Gizmos.DrawLine(centerIceFaceoff.position + Vector3.left * 0.5f, centerIceFaceoff.position + Vector3.right * 0.5f); Gizmos.DrawLine(centerIceFaceoff.position + Vector3.forward * 0.5f, centerIceFaceoff.position + Vector3.back * 0.5f); #if UNITY_EDITOR UnityEditor.Handles.Label(centerIceFaceoff.position + Vector3.up, "Center Ice"); #endif } if (homeZoneFaceoff != null) { Gizmos.color = Color.red; Gizmos.DrawWireSphere(homeZoneFaceoff.position, 0.3f); #if UNITY_EDITOR UnityEditor.Handles.Label(homeZoneFaceoff.position + Vector3.up, "Home Zone"); #endif } if (awayZoneFaceoff != null) { Gizmos.color = Color.green; Gizmos.DrawWireSphere(awayZoneFaceoff.position, 0.3f); #if UNITY_EDITOR UnityEditor.Handles.Label(awayZoneFaceoff.position + Vector3.up, "Away Zone"); #endif } } }