using System.Collections; using Mirror; using UnityEngine; using UnityEngine.EventSystems; public class Puck : NetworkBehaviour { [HideInInspector]public Rigidbody2D rb; [SyncVar] public bool isSelected; public LineRenderer lineRenderer; [SyncVar] public Team team; public GameObject redTeamMarker; public GameObject blueTeamMarker; public Transform selectedMarker; public float markerRotateSpeed; public float markerBounceIntensity; public float markerBounceSpeed; Vector3 markerStartScale; Vector3 startPosition; float bounceSinA; void OnValidate() { UpdateTeam(); } void Awake() { UpdateTeam(); markerStartScale = selectedMarker.localScale; rb=GetComponent(); startPosition = transform.position; } void UpdateTeam(){ redTeamMarker.SetActive(team == Team.Red); blueTeamMarker.SetActive(team == Team.Blue); } void Start() { GameEvents.OnSelectedPuckChanged += OnSelectedPuckChanged; GameManager.OnTeamChanged += OnTeamChanged; GameManager.instance.RegisterPuck(this); } void OnDestroy() { GameEvents.OnSelectedPuckChanged -= OnSelectedPuckChanged; GameManager.OnTeamChanged -= OnTeamChanged; GameManager.instance.DisposePuck(this); } public Vector3 lineEnd; void Update() { if (isSelected && lineRenderer != null) { Vector3 worldEnd = Camera.main.ScreenToWorldPoint(new Vector3(NetPlayer.curPosition.x, NetPlayer.curPosition.y, Camera.main.nearClipPlane)); lineEnd = transform.InverseTransformPoint(worldEnd); float clamp = GameManager.instance.puckDragClampMax; lineEnd = Vector2.ClampMagnitude(lineEnd, clamp); if (NetPlayer.localPlayer != null && team == NetPlayer.localPlayer.myTeam && GameManager.instance.SelectedTeam == team) { float baseStretch = lineEnd.magnitude / clamp; float distanceMultiplier = GameManager.instance.GetCameraStretchDistanceMultiplier(transform.position); CameraEffects.instance.SetStretchFactor(baseStretch * distanceMultiplier); } // Only two points for the line lineRenderer.positionCount = 2; lineRenderer.SetPosition(0, Vector3.zero); lineRenderer.SetPosition(1, new Vector3(lineEnd.x, lineEnd.y, 0)); } selectedMarker.gameObject.SetActive(GetMarkerVisibility()); if(GameManager.instance.SelectedTeam == team){ selectedMarker.Rotate(new Vector3(0,0,1), markerRotateSpeed * Time.deltaTime); bounceSinA += Time.deltaTime * markerBounceSpeed; float bounce = Mathf.Sin(bounceSinA) * markerBounceIntensity; selectedMarker.localScale = markerStartScale + (Vector3.one * bounce); } } bool GetMarkerVisibility(){ if(GameManager.instance.m_isMoving){return false;} if(NetPlayer.localPlayer == null){return false;} if(NetPlayer.localPlayer.myTeam != team){return false;} if(GameManager.instance.SelectedTeam == team){ if(GameManager.NoPuckSelected){ return true; }else{ return isSelected; } } return false; } void OnSelectedPuckChanged(Puck puck) { isSelected = puck == this; lineRenderer.enabled = isSelected; if(NetPlayer.localPlayer == null){return;} if(team != NetPlayer.localPlayer.myTeam){ lineRenderer.widthMultiplier = 0; } } void OnTeamChanged(Team team){ } void OnCollisionEnter2D(Collision2D collision) { if (!collision.collider.CompareTag("Puck")) return; // Both pucks get this callback; play once per contact. if (gameObject.GetInstanceID() >= collision.gameObject.GetInstanceID()) return; float otherSpeed = collision.relativeVelocity.magnitude; Debug.Log("Puck collision speed: " + otherSpeed); float maxVolSpeed =5f; float vol = Mathf.Clamp(otherSpeed / maxVolSpeed,0.1f,1); if (AudioManager.instance != null){ AudioManager.instance.PlayPuckHit(vol); if(isServer){ RpcPuckHitAudio(vol); } } } [ClientRpc] void RpcPuckHitAudio(float vol){ AudioManager.instance.PlayPuckHit(vol); } public void Reset(Vector3? position = null, float duration = 0.5f) { Vector3 pos = position ?? startPosition; StartCoroutine(CoroutineReset(pos, duration)); } Coroutine coroutineScheduleReset; public void ScheduleReset(Vector3 position, float duration = 0.5f){ coroutineScheduleReset = StartCoroutine(CoroutineScheduleReset(position, duration)); } public void UnscheduleReset(){ if(coroutineScheduleReset != null){ StopCoroutine(coroutineScheduleReset); } } IEnumerator CoroutineScheduleReset(Vector3 position, float duration){ while(GameManager.isMoving){ yield return null; } Debug.Log("Resetting puck", gameObject); Vector3 dir = position - transform.position; Vector3 centerDir = Vector3.zero - transform.position; dir = dir.normalized; centerDir = centerDir.normalized; // Clamp direction to within 30 degrees of centerDir if needed float maxAngle = 30f; float angle = Vector3.Angle(dir, centerDir); if (angle > maxAngle) { dir = Vector3.Slerp(centerDir, dir, maxAngle / angle).normalized; } position += dir * 1.25f; Reset(position, duration); } IEnumerator CoroutineReset(Vector3 pos, float duration){ float t=0; Vector3 pos1 = transform.position; Quaternion rot1 = transform.rotation; while(t