| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175 |
- using UnityEngine;
- using UnityEngine.InputSystem;
- /// <summary>
- /// Simple camera movement controller for map navigation.
- /// Supports WASD/arrow keys, right-click drag, and Q/E or mouse wheel zoom.
- /// </summary>
- [RequireComponent(typeof(Camera))]
- public class MazeCameraController : MonoBehaviour
- {
- [Header("Movement")]
- [SerializeField] private float moveSpeed = 20f;
- [SerializeField] private float dragSpeed = 1f;
- [Header("Zoom")]
- [SerializeField] private float zoomSpeed = 25f;
- [SerializeField] private float zoomMin = 5f;
- [SerializeField] private float zoomMax = 120f;
- [Header("Optional Bounds")]
- [SerializeField] private bool useBounds = false;
- [SerializeField] private Vector2 minBounds = new Vector2(-100f, -100f);
- [SerializeField] private Vector2 maxBounds = new Vector2(100f, 100f);
- private Camera cameraComponent;
- private Vector3 targetPosition;
- private Vector3 lastMousePosition;
- private bool isDragging;
- private void Awake()
- {
- cameraComponent = GetComponent<Camera>();
- targetPosition = transform.position;
- }
- private void Update()
- {
- HandleKeyboardMovement();
- HandleMouseDrag();
- HandleZoom();
- ApplyPosition();
- }
- private void HandleKeyboardMovement()
- {
- var keyboard = Keyboard.current;
- if (keyboard == null)
- {
- return;
- }
- float horizontal = 0f;
- if (keyboard.aKey.isPressed || keyboard.leftArrowKey.isPressed)
- {
- horizontal -= 1f;
- }
- if (keyboard.dKey.isPressed || keyboard.rightArrowKey.isPressed)
- {
- horizontal += 1f;
- }
- float vertical = 0f;
- if (keyboard.sKey.isPressed || keyboard.downArrowKey.isPressed)
- {
- vertical -= 1f;
- }
- if (keyboard.wKey.isPressed || keyboard.upArrowKey.isPressed)
- {
- vertical += 1f;
- }
- if (horizontal != 0f || vertical != 0f)
- {
- Vector3 right = transform.right;
- Vector3 forward = Vector3.Cross(transform.right, Vector3.up).normalized;
- Vector3 worldMove = (right * horizontal + forward * vertical).normalized;
- targetPosition += worldMove * moveSpeed * Time.deltaTime;
- }
- if (keyboard.qKey.isPressed)
- {
- Zoom(-zoomSpeed * Time.deltaTime);
- }
- else if (keyboard.eKey.isPressed)
- {
- Zoom(zoomSpeed * Time.deltaTime);
- }
- }
- private void HandleMouseDrag()
- {
- var mouse = Mouse.current;
- if (mouse == null)
- {
- return;
- }
- if (mouse.rightButton.wasPressedThisFrame)
- {
- isDragging = true;
- Vector2 position = mouse.position.ReadValue();
- lastMousePosition = new Vector3(position.x, position.y, 0f);
- }
- if (mouse.rightButton.wasReleasedThisFrame)
- {
- isDragging = false;
- }
- if (isDragging && mouse.rightButton.isPressed)
- {
- Vector2 position = mouse.position.ReadValue();
- Vector3 currentMousePosition = new Vector3(position.x, position.y, 0f);
- if (currentMousePosition != lastMousePosition)
- {
- Vector3 dragDelta = GetDragWorldDelta(lastMousePosition, currentMousePosition);
- targetPosition += dragDelta * dragSpeed;
- lastMousePosition = currentMousePosition;
- }
- }
- }
- private void HandleZoom()
- {
- var mouse = Mouse.current;
- if (mouse != null)
- {
- float scroll = mouse.scroll.ReadValue().y;
- if (scroll != 0f)
- {
- Zoom(-scroll * zoomSpeed * Time.deltaTime);
- }
- }
- }
- private void Zoom(float amount)
- {
- if (cameraComponent.orthographic)
- {
- cameraComponent.orthographicSize = Mathf.Clamp(cameraComponent.orthographicSize + amount, zoomMin, zoomMax);
- }
- else
- {
- cameraComponent.fieldOfView = Mathf.Clamp(cameraComponent.fieldOfView + amount, zoomMin, zoomMax);
- }
- }
- private Vector3 GetDragWorldDelta(Vector3 previousScreenPosition, Vector3 currentScreenPosition)
- {
- Plane dragPlane = new Plane(-transform.forward, transform.position);
- Ray previousRay = cameraComponent.ScreenPointToRay(previousScreenPosition);
- Ray currentRay = cameraComponent.ScreenPointToRay(currentScreenPosition);
- if (dragPlane.Raycast(previousRay, out float previousDistance) && dragPlane.Raycast(currentRay, out float currentDistance))
- {
- Vector3 previousWorld = previousRay.GetPoint(previousDistance);
- Vector3 currentWorld = currentRay.GetPoint(currentDistance);
- return previousWorld - currentWorld;
- }
- return Vector3.zero;
- }
- private void ApplyPosition()
- {
- Vector3 newPosition = targetPosition;
- if (useBounds)
- {
- newPosition.x = Mathf.Clamp(newPosition.x, minBounds.x, maxBounds.x);
- newPosition.z = Mathf.Clamp(newPosition.z, minBounds.y, maxBounds.y);
- }
- transform.position = newPosition;
- }
- }
|