using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.InputSystem; namespace AsteroidGame { public class CameraController : MonoBehaviour { private CameraControllActions cameraActions; private InputAction movement; private Transform cameraTransform; // Horizontal Movement [SerializeField] private float maxSpeed = 5f; private float speed; [SerializeField] private float acceleration = 10f; [SerializeField] private float damping = 15f; //Vertial Motion - Zooming [SerializeField] private float stepSize = 2f; [SerializeField] private float zoomDampening = 7.5f; [SerializeField] private float minHeight = 5f; [SerializeField] private float maxHeight = 50f; [SerializeField] private float zoomSpeed = 2f; //Rotation [SerializeField] private float maxRotationSpeed = 1f; //Screen Edge Motion [SerializeField] [Range(0f, 0.1f)] private float edgeTolerance = 0.05f; [SerializeField] private bool useScreenEdge = false; private Vector3 targetPosition; private float zoomHeight; private Vector3 horizontalVelocity; private Vector3 lastPosition; private Plane cameraPlane; Vector3 startDrag; private void Awake() { cameraActions = new CameraControllActions(); cameraTransform = this.GetComponentInChildren().transform; } private void OnEnable() { cameraPlane = new Plane(Vector3.up, Vector3.zero); zoomHeight = cameraTransform.localPosition.y; cameraTransform.LookAt(this.transform); lastPosition = this.transform.position; movement = cameraActions.Camera.Movement; cameraActions.Camera.RotateCamera.performed += RotateCamera; cameraActions.Camera.ZoomCamera.performed += ZoomCamera; cameraActions.Camera.Enable(); } private void OnDisable() { cameraActions.Camera.RotateCamera.performed -= RotateCamera; cameraActions.Camera.ZoomCamera.performed -= ZoomCamera; cameraActions.Disable(); } private void Update() { GetKeyboardMovement(); if (useScreenEdge) { CheckMouseAtScreenEdge(); } DragCamera(); UpdateVelocity(); UpdateCameraPosition(); UpdateBasePosition(); } private void UpdateVelocity() { horizontalVelocity = (this.transform.position - lastPosition) / Time.deltaTime; horizontalVelocity.y = 0; lastPosition = this.transform.position; } private void GetKeyboardMovement() { Vector3 inputValue = movement.ReadValue().x * GetCameraRight() + movement.ReadValue().y * GetCameraForward(); inputValue = inputValue.normalized; if (inputValue.sqrMagnitude > 0.1f) { targetPosition += inputValue; } } private Vector3 GetCameraRight() { Vector3 right = cameraTransform.right; right.y = 0; return right; } private Vector3 GetCameraForward() { Vector3 forward = cameraTransform.forward; forward.y = 0; return forward; } private void UpdateBasePosition() { if (targetPosition.sqrMagnitude > 0.1f) { speed = Mathf.Lerp(speed, maxSpeed, Time.deltaTime * acceleration); transform.position += targetPosition * speed * Time.deltaTime; } else { horizontalVelocity = Vector3.Lerp(horizontalVelocity, Vector3.zero, Time.deltaTime * damping); transform.position += horizontalVelocity * Time.deltaTime; } targetPosition = Vector3.zero; } private void RotateCamera(InputAction.CallbackContext inputValue) { if (!Mouse.current.middleButton.isPressed) { return; } float value = inputValue.ReadValue().x; transform.rotation = Quaternion.Euler(0f, value * maxRotationSpeed + transform.rotation.eulerAngles.y, 0f); } private void ZoomCamera(InputAction.CallbackContext inputValue) { float value = -inputValue.ReadValue().y / 100f; if (Mathf.Abs(value) > 0.1f) { zoomHeight = cameraTransform.localPosition.y + value * stepSize; if (zoomHeight < minHeight) zoomHeight = minHeight; else if (zoomHeight > maxHeight) zoomHeight = maxHeight; } } private void UpdateCameraPosition() { Vector3 zoomTarget = new Vector3(cameraTransform.localPosition.x, zoomHeight, cameraTransform.localPosition.z); zoomTarget -= zoomSpeed * (zoomHeight - cameraTransform.localPosition.y) * Vector3.forward; cameraTransform.localPosition = Vector3.Lerp(cameraTransform.localPosition, zoomTarget, Time.deltaTime * zoomDampening); cameraTransform.LookAt(this.transform); } private void CheckMouseAtScreenEdge() { Vector2 mousePosition = Mouse.current.position.ReadValue(); Vector3 moveDirection = Vector3.zero; if (mousePosition.x < edgeTolerance * Screen.width) moveDirection += -GetCameraRight(); else if (mousePosition.x > (1f - edgeTolerance) * Screen.width) moveDirection += GetCameraRight(); if (mousePosition.y < edgeTolerance * Screen.height) moveDirection += -GetCameraForward(); else if (mousePosition.y > (1f - edgeTolerance) * Screen.height) moveDirection += GetCameraForward(); targetPosition += moveDirection; } private void DragCamera() { if (!Mouse.current.rightButton.isPressed) { return; } Ray ray = Camera.main.ScreenPointToRay(Mouse.current.position.ReadValue()); if (cameraPlane.Raycast(ray,out float distance)) { if (Mouse.current.rightButton.wasPressedThisFrame) startDrag = ray.GetPoint(distance); else targetPosition += startDrag - ray.GetPoint(distance); } } } }