using System.Collections; using Mirror; using UnityEngine; public class Ball : NetworkBehaviour { [HideInInspector]public Rigidbody2D rb; Vector3 startPosition; public float wallDetectionLength = 0.5f; public float wallStuckFixForce = 1f; public float maxWallStuckVelocity = 5f; public LayerMask wallLayerMask; public float distToGoal; public float nearGoalThreshold = 2.5f; void Awake() { rb = GetComponent(); startPosition = transform.position; } public void Reset(float duration){ StartCoroutine(CoroutineReset(duration)); } IEnumerator CoroutineReset(float duration){ float t=0; Vector3 pos1 = transform.position; Quaternion rot1 = transform.rotation; while (t < duration){ t+=Time.deltaTime; transform.position = Vector3.Lerp(pos1, startPosition, t / duration); transform.rotation = Quaternion.Lerp(rot1, Quaternion.identity, t/duration); yield return null; } } public bool touchingB,touchingL,touchingR,touchingT = false; void Update() { CheckNearGoal(); if(!isServer){return;} WallDetection(); } void CheckNearGoal(){ Goal[] goals = FindObjectsByType(FindObjectsSortMode.None); float closestDist = float.MaxValue; foreach(Goal goal in goals){ float dist = Vector3.Distance(transform.position, goal.transform.position); if(dist < closestDist){ closestDist = dist; } } distToGoal = closestDist; AudioManager.instance.SetIsBallNearGoal(distToGoal < nearGoalThreshold); } void OnCollisionEnter2D(Collision2D collision) { float otherSpeed = collision.relativeVelocity.magnitude; float velocityMult = 1- Mathf.Clamp01(rb.linearVelocity.magnitude / maxWallStuckVelocity); // Debug.Log($"{collision.collider.name} hit ball @ {otherSpeed}, ball speed: {rb.linearVelocity.magnitude}"); int mult=0; if(touchingB){ mult++; } if(touchingT){ mult++; } if(touchingL){ mult++; } if(touchingR){ mult++; } velocityMult *= mult; if (touchingR) { rb.AddForce(Vector2.left * otherSpeed *wallStuckFixForce * velocityMult ); } if (touchingL) { rb.AddForce(Vector2.right * otherSpeed * wallStuckFixForce * velocityMult ); } if (touchingT) { rb.AddForce(Vector2.down * otherSpeed * wallStuckFixForce * velocityMult ); } if (touchingB) { rb.AddForce(Vector2.up *otherSpeed * wallStuckFixForce * velocityMult ); } float maxVolSpeed =5f; float vol = Mathf.Clamp01(otherSpeed / maxVolSpeed); if(collision.collider.CompareTag("wall")){ AudioManager.instance.PlayWallHit(vol); if (isServer) ReplayRecorder.RecordHit("ball_wall", vol, this); RpcWallHitAudio(vol); } else if(collision.collider.CompareTag("Puck")){ AudioManager.instance.PlayBallHit(vol); if (isServer) ReplayRecorder.RecordHit("ball_puck", vol, this); RpcBallHitAudio(vol); } } [ClientRpc] void RpcWallHitAudio(float vol){ AudioManager.instance.PlayWallHit(vol); } [ClientRpc] void RpcBallHitAudio(float vol){ AudioManager.instance.PlayBallHit(vol); } void WallDetection(){ // Linecast for each direction Vector3 pos = transform.position; RaycastHit2D hitL = Physics2D.Linecast(pos, pos + Vector3.left * wallDetectionLength, wallLayerMask); touchingL = hitL.collider != null; RaycastHit2D hitR = Physics2D.Linecast(pos, pos + Vector3.right * wallDetectionLength, wallLayerMask); touchingR = hitR.collider != null; RaycastHit2D hitT = Physics2D.Linecast(pos, pos + Vector3.up * wallDetectionLength, wallLayerMask); touchingT = hitT.collider != null; RaycastHit2D hitB = Physics2D.Linecast(pos, pos + Vector3.down * wallDetectionLength, wallLayerMask); touchingB = hitB.collider != null; } void OnDrawGizmos() { Gizmos.color = touchingL ? Color.red : Color.green; Gizmos.DrawLine(transform.position, transform.position + (Vector3.left * wallDetectionLength)); Gizmos.color = touchingR ? Color.red : Color.green; Gizmos.DrawLine(transform.position, transform.position + (Vector3.right * wallDetectionLength)); Gizmos.color = touchingT ? Color.red : Color.green; Gizmos.DrawLine(transform.position, transform.position + (Vector3.up * wallDetectionLength)); Gizmos.color = touchingB ? Color.red : Color.green; Gizmos.DrawLine(transform.position, transform.position + (Vector3.down * wallDetectionLength)); } }