| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697 |
- using UnityEngine;
- using UnityEngine.InputSystem;
- [RequireComponent(typeof(Collider2D))]
- [RequireComponent(typeof(Rigidbody2D))]
- public class PaddleScript : MonoBehaviour
- {
- [Header("Movement")]
- [SerializeField] private float moveSpeed = 10f;
- [Header("Bounds")]
- [Tooltip("Extra gap between the paddle edge and the camera edge.")]
- [SerializeField] private float edgePadding = 0.1f;
- private float _minX;
- private float _maxX;
- private float _halfWidth;
- private bool _useMouse = true;
- void Awake()
- {
- // Paddle is player-driven via transform — kinematic prevents physics forces from interfering.
- GetComponent<Rigidbody2D>().bodyType = RigidbodyType2D.Kinematic;
- }
- void Start()
- {
- _halfWidth = GetComponent<Collider2D>().bounds.extents.x;
- // Derive horizontal limits from the camera viewport so the paddle never leaves the screen.
- Camera cam = Camera.main;
- float distToCamera = Mathf.Abs(cam.transform.position.z);
- _minX = cam.ViewportToWorldPoint(new Vector3(0f, 0f, distToCamera)).x + _halfWidth + edgePadding;
- _maxX = cam.ViewportToWorldPoint(new Vector3(1f, 0f, distToCamera)).x - _halfWidth - edgePadding;
- }
- void Update()
- {
- var keyboard = Keyboard.current;
- var mouse = Mouse.current;
- float keyInput = 0f;
- if (keyboard != null)
- {
- if (keyboard.aKey.isPressed || keyboard.leftArrowKey.isPressed) keyInput -= 1f;
- if (keyboard.dKey.isPressed || keyboard.rightArrowKey.isPressed) keyInput += 1f;
- }
- // Any keyboard movement disables mouse; any mouse click re-enables mouse.
- if (Mathf.Abs(keyInput) > 0.01f)
- _useMouse = false;
- else if (mouse != null && mouse.leftButton.wasPressedThisFrame)
- _useMouse = true;
- Vector3 pos = transform.position;
- if (!_useMouse && Mathf.Abs(keyInput) > 0.01f)
- {
- // Keyboard: direct movement at moveSpeed.
- pos.x += keyInput * moveSpeed * Time.deltaTime;
- }
- else if (_useMouse && mouse != null)
- {
- // Mouse: smoothly move toward the cursor's world X at moveSpeed.
- Camera cam = Camera.main;
- Vector2 mouseScreen = mouse.position.ReadValue();
- Vector3 mouseWorld = cam.ScreenToWorldPoint(
- new Vector3(mouseScreen.x, mouseScreen.y, Mathf.Abs(cam.transform.position.z)));
- pos.x = Mathf.MoveTowards(pos.x, mouseWorld.x, moveSpeed * Time.deltaTime);
- }
- pos.x = Mathf.Clamp(pos.x, _minX, _maxX);
- transform.position = pos;
- }
- private void OnCollisionEnter2D(Collision2D collision)
- {
- if (!collision.gameObject.CompareTag("Ball"))
- return;
- Rigidbody2D ballRb = collision.rigidbody;
- if (ballRb == null)
- return;
- // Map hit position to [-1, 1]: -1 = left edge, 0 = centre, +1 = right edge.
- float hitOffset = (collision.transform.position.x - transform.position.x) / _halfWidth;
- hitOffset = Mathf.Clamp(hitOffset, -1f, 1f);
- // Preserve the ball's current speed so movement effects still apply.
- BallScript ballScript = collision.gameObject.GetComponent<BallScript>();
- float speed = ballScript != null ? ballScript.GetCurrentSpeed() : 10f;
- // A centre hit goes straight up; edge hits angle up to 75 degrees to either side.
- float angle = hitOffset * 75f * Mathf.Deg2Rad;
- ballRb.linearVelocity = new Vector2(Mathf.Sin(angle), Mathf.Cos(angle)) * speed;
- }
- }
|