using UnityEngine; public class EyeBall : BallBase { private static float reorientationAngleDegrees = 3f; private Bounds boardBounds; private Collider2D selfCollider; private bool hasBoardBounds = false; private float magnetBounceDuration = 0.35f; private float magnetCenterLeeway = 0.12f; private MagnetBounceAxisState xMagnetBounceState; private MagnetBounceAxisState yMagnetBounceState; // Start is called once before the first execution of Update after the MonoBehaviour is created void Start() { audioSource = GetComponent(); animator = GetComponent(); selfCollider = GetComponent(); speed = new Vector2(Random.Range(-0.05f, 0.05f), Random.Range(-0.05f, 0.05f)); hasBoardBounds = TryCacheGameBoardBounds(out boardBounds); audioSource.PlayOneShot(spawnSound); } // Update is called once per frame void FixedUpdate() { AnimatorStateInfo stateInfo = animator.GetCurrentAnimatorStateInfo(0); // Adjust eye ball direction based on the player's bar if active. var barSegments = GameObject.FindGameObjectsWithTag("Bar"); if (barSegments.Length > 0) { // For simplicity, just take the first bar segment found. var barSegment = barSegments[0]; Vector3 directionToBar = (barSegment.transform.position - transform.position).normalized; float currentSpeed = speed.magnitude; if (currentSpeed > 0f) { float signedAngle = Vector2.SignedAngle(speed.normalized, (Vector2)directionToBar); float clampedAngle = Mathf.Clamp(signedAngle, -reorientationAngleDegrees, reorientationAngleDegrees); Vector2 smoothDirection = (Vector2)(Quaternion.Euler(0f, 0f, clampedAngle) * speed.normalized); speed = smoothDirection * currentSpeed; // Maintain current speed magnitude } } if (stateInfo.IsName("EyeBallMove")) { transform.Translate(speed); if (affectedByMagnet && hasBoardBounds) { Vector3 currentPosition = transform.position; currentPosition.x = ApplyMagnetBounceAxis( currentPosition.x, boardBounds.min.x, boardBounds.max.x, magnetActiveLeftRight, ref xMagnetBounceState, selfCollider != null ? selfCollider.bounds.extents.x : 0.0f, magnetBounceDuration, magnetCenterLeeway ); currentPosition.y = ApplyMagnetBounceAxis( currentPosition.y, boardBounds.min.y, boardBounds.max.y, magnetActiveTopBottom, ref yMagnetBounceState, selfCollider != null ? selfCollider.bounds.extents.y : 0.0f, magnetBounceDuration, magnetCenterLeeway ); transform.position = currentPosition; } } } void OnCollisionEnter2D(Collision2D collision) { // EyeBall only bounces off walls, not other balls if (collision.gameObject.CompareTag("Wall")) { ContactPoint2D contact = collision.GetContact(0); speed = Vector2.Reflect(speed, contact.normal); } } }