MazeCameraController.cs 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. using UnityEngine;
  2. using UnityEngine.InputSystem;
  3. /// <summary>
  4. /// Simple camera movement controller for map navigation.
  5. /// Supports WASD/arrow keys, right-click drag, and Q/E or mouse wheel zoom.
  6. /// </summary>
  7. [RequireComponent(typeof(Camera))]
  8. public class MazeCameraController : MonoBehaviour
  9. {
  10. [Header("Movement")]
  11. [SerializeField] private float moveSpeed = 20f;
  12. [SerializeField] private float dragSpeed = 1f;
  13. [Header("Zoom")]
  14. [SerializeField] private float zoomSpeed = 25f;
  15. [SerializeField] private float zoomMin = 5f;
  16. [SerializeField] private float zoomMax = 120f;
  17. [Header("Optional Bounds")]
  18. [SerializeField] private bool useBounds = false;
  19. [SerializeField] private Vector2 minBounds = new Vector2(-100f, -100f);
  20. [SerializeField] private Vector2 maxBounds = new Vector2(100f, 100f);
  21. private Camera cameraComponent;
  22. private Vector3 targetPosition;
  23. private Vector3 lastMousePosition;
  24. private bool isDragging;
  25. private void Awake()
  26. {
  27. cameraComponent = GetComponent<Camera>();
  28. targetPosition = transform.position;
  29. }
  30. private void Update()
  31. {
  32. HandleKeyboardMovement();
  33. HandleMouseDrag();
  34. HandleZoom();
  35. ApplyPosition();
  36. }
  37. private void HandleKeyboardMovement()
  38. {
  39. var keyboard = Keyboard.current;
  40. if (keyboard == null)
  41. {
  42. return;
  43. }
  44. float horizontal = 0f;
  45. if (keyboard.aKey.isPressed || keyboard.leftArrowKey.isPressed)
  46. {
  47. horizontal -= 1f;
  48. }
  49. if (keyboard.dKey.isPressed || keyboard.rightArrowKey.isPressed)
  50. {
  51. horizontal += 1f;
  52. }
  53. float vertical = 0f;
  54. if (keyboard.sKey.isPressed || keyboard.downArrowKey.isPressed)
  55. {
  56. vertical -= 1f;
  57. }
  58. if (keyboard.wKey.isPressed || keyboard.upArrowKey.isPressed)
  59. {
  60. vertical += 1f;
  61. }
  62. if (horizontal != 0f || vertical != 0f)
  63. {
  64. Vector3 right = transform.right;
  65. Vector3 forward = Vector3.Cross(transform.right, Vector3.up).normalized;
  66. Vector3 worldMove = (right * horizontal + forward * vertical).normalized;
  67. targetPosition += worldMove * moveSpeed * Time.deltaTime;
  68. }
  69. if (keyboard.qKey.isPressed)
  70. {
  71. Zoom(-zoomSpeed * Time.deltaTime);
  72. }
  73. else if (keyboard.eKey.isPressed)
  74. {
  75. Zoom(zoomSpeed * Time.deltaTime);
  76. }
  77. }
  78. private void HandleMouseDrag()
  79. {
  80. var mouse = Mouse.current;
  81. if (mouse == null)
  82. {
  83. return;
  84. }
  85. if (mouse.rightButton.wasPressedThisFrame)
  86. {
  87. isDragging = true;
  88. Vector2 position = mouse.position.ReadValue();
  89. lastMousePosition = new Vector3(position.x, position.y, 0f);
  90. }
  91. if (mouse.rightButton.wasReleasedThisFrame)
  92. {
  93. isDragging = false;
  94. }
  95. if (isDragging && mouse.rightButton.isPressed)
  96. {
  97. Vector2 position = mouse.position.ReadValue();
  98. Vector3 currentMousePosition = new Vector3(position.x, position.y, 0f);
  99. if (currentMousePosition != lastMousePosition)
  100. {
  101. Vector3 dragDelta = GetDragWorldDelta(lastMousePosition, currentMousePosition);
  102. targetPosition += dragDelta * dragSpeed;
  103. lastMousePosition = currentMousePosition;
  104. }
  105. }
  106. }
  107. private void HandleZoom()
  108. {
  109. var mouse = Mouse.current;
  110. if (mouse != null)
  111. {
  112. float scroll = mouse.scroll.ReadValue().y;
  113. if (scroll != 0f)
  114. {
  115. Zoom(-scroll * zoomSpeed * Time.deltaTime);
  116. }
  117. }
  118. }
  119. private void Zoom(float amount)
  120. {
  121. if (cameraComponent.orthographic)
  122. {
  123. cameraComponent.orthographicSize = Mathf.Clamp(cameraComponent.orthographicSize + amount, zoomMin, zoomMax);
  124. }
  125. else
  126. {
  127. cameraComponent.fieldOfView = Mathf.Clamp(cameraComponent.fieldOfView + amount, zoomMin, zoomMax);
  128. }
  129. }
  130. private Vector3 GetDragWorldDelta(Vector3 previousScreenPosition, Vector3 currentScreenPosition)
  131. {
  132. Plane dragPlane = new Plane(-transform.forward, transform.position);
  133. Ray previousRay = cameraComponent.ScreenPointToRay(previousScreenPosition);
  134. Ray currentRay = cameraComponent.ScreenPointToRay(currentScreenPosition);
  135. if (dragPlane.Raycast(previousRay, out float previousDistance) && dragPlane.Raycast(currentRay, out float currentDistance))
  136. {
  137. Vector3 previousWorld = previousRay.GetPoint(previousDistance);
  138. Vector3 currentWorld = currentRay.GetPoint(currentDistance);
  139. return previousWorld - currentWorld;
  140. }
  141. return Vector3.zero;
  142. }
  143. private void ApplyPosition()
  144. {
  145. Vector3 newPosition = targetPosition;
  146. if (useBounds)
  147. {
  148. newPosition.x = Mathf.Clamp(newPosition.x, minBounds.x, maxBounds.x);
  149. newPosition.z = Mathf.Clamp(newPosition.z, minBounds.y, maxBounds.y);
  150. }
  151. transform.position = newPosition;
  152. }
  153. }