CameraController.cs 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. using UnityEngine;
  2. public class CameraController : MonoBehaviour
  3. {
  4. [Header("Movement Settings")]
  5. [SerializeField] private float panSpeed = 5f;
  6. [SerializeField] private float zoomSpeed = 2f;
  7. [SerializeField] private float rotationSpeed = 100f;
  8. [Header("Limits")]
  9. [SerializeField] private float minZoom = 5f;
  10. [SerializeField] private float maxZoom = 50f;
  11. [SerializeField] private Vector2 panLimitX = new Vector2(-50f, 50f);
  12. [SerializeField] private Vector2 panLimitZ = new Vector2(-50f, 50f);
  13. [Header("Input Settings")]
  14. [SerializeField] private KeyCode panKey = KeyCode.LeftShift;
  15. [SerializeField] private KeyCode rotateKey = KeyCode.LeftAlt;
  16. private Camera cam;
  17. private Vector3 lastMousePosition;
  18. private bool isDragging = false;
  19. private void Start()
  20. {
  21. cam = GetComponent<Camera>();
  22. if (cam == null)
  23. {
  24. cam = Camera.main;
  25. }
  26. // Set initial camera position for hotel view
  27. transform.position = new Vector3(0, 15f, -20f);
  28. transform.rotation = Quaternion.Euler(45f, 0f, 0f);
  29. }
  30. private void Update()
  31. {
  32. HandleMovementInput();
  33. HandleZoomInput();
  34. HandleRotationInput();
  35. }
  36. private void HandleMovementInput()
  37. {
  38. // WASD movement
  39. Vector3 movement = Vector3.zero;
  40. if (Input.GetKey(KeyCode.W))
  41. movement += transform.forward;
  42. if (Input.GetKey(KeyCode.S))
  43. movement -= transform.forward;
  44. if (Input.GetKey(KeyCode.A))
  45. movement -= transform.right;
  46. if (Input.GetKey(KeyCode.D))
  47. movement += transform.right;
  48. // Apply movement with speed adjustment based on camera height
  49. float speedMultiplier = transform.position.y / 10f;
  50. movement *= panSpeed * speedMultiplier * Time.deltaTime;
  51. // Clamp position within limits
  52. Vector3 newPosition = transform.position + movement;
  53. newPosition.x = Mathf.Clamp(newPosition.x, panLimitX.x, panLimitX.y);
  54. newPosition.z = Mathf.Clamp(newPosition.z, panLimitZ.x, panLimitZ.y);
  55. transform.position = newPosition;
  56. // Mouse drag panning
  57. HandleMousePanning();
  58. }
  59. private void HandleMousePanning()
  60. {
  61. if (Input.GetMouseButtonDown(2) || (Input.GetMouseButtonDown(0) && Input.GetKey(panKey))) // Middle mouse or Shift+Left mouse
  62. {
  63. isDragging = true;
  64. lastMousePosition = Input.mousePosition;
  65. }
  66. else if (Input.GetMouseButtonUp(2) || Input.GetMouseButtonUp(0))
  67. {
  68. isDragging = false;
  69. }
  70. if (isDragging)
  71. {
  72. Vector3 mouseDelta = Input.mousePosition - lastMousePosition;
  73. // Convert mouse movement to world movement
  74. Vector3 worldDelta = new Vector3(-mouseDelta.x, 0, -mouseDelta.y) * panSpeed * 0.01f;
  75. // Apply relative to camera orientation
  76. worldDelta = transform.TransformDirection(worldDelta);
  77. worldDelta.y = 0; // Keep camera at same height during panning
  78. Vector3 newPosition = transform.position + worldDelta;
  79. newPosition.x = Mathf.Clamp(newPosition.x, panLimitX.x, panLimitX.y);
  80. newPosition.z = Mathf.Clamp(newPosition.z, panLimitZ.x, panLimitZ.y);
  81. transform.position = newPosition;
  82. lastMousePosition = Input.mousePosition;
  83. }
  84. }
  85. private void HandleZoomInput()
  86. {
  87. float scroll = Input.GetAxis("Mouse ScrollWheel");
  88. if (Mathf.Abs(scroll) > 0.01f)
  89. {
  90. // For orthographic camera, adjust orthographicSize
  91. if (cam.orthographic)
  92. {
  93. cam.orthographicSize -= scroll * zoomSpeed;
  94. cam.orthographicSize = Mathf.Clamp(cam.orthographicSize, minZoom, maxZoom);
  95. }
  96. else
  97. {
  98. // For perspective camera, move camera forward/backward
  99. Vector3 zoomDirection = transform.forward * scroll * zoomSpeed;
  100. Vector3 newPosition = transform.position + zoomDirection;
  101. // Limit zoom by height
  102. if (newPosition.y >= minZoom && newPosition.y <= maxZoom)
  103. {
  104. transform.position = newPosition;
  105. }
  106. }
  107. }
  108. }
  109. private void HandleRotationInput()
  110. {
  111. if (Input.GetMouseButton(1) || (Input.GetMouseButton(0) && Input.GetKey(rotateKey))) // Right mouse or Alt+Left mouse
  112. {
  113. float mouseX = Input.GetAxis("Mouse X") * rotationSpeed * Time.deltaTime;
  114. float mouseY = -Input.GetAxis("Mouse Y") * rotationSpeed * Time.deltaTime;
  115. // Rotate around Y axis (horizontal rotation)
  116. transform.Rotate(Vector3.up, mouseX, Space.World);
  117. // Rotate around local X axis (vertical rotation)
  118. transform.Rotate(Vector3.right, mouseY, Space.Self);
  119. // Clamp vertical rotation
  120. Vector3 eulerAngles = transform.eulerAngles;
  121. if (eulerAngles.x > 180f)
  122. eulerAngles.x -= 360f;
  123. eulerAngles.x = Mathf.Clamp(eulerAngles.x, -80f, 80f);
  124. transform.eulerAngles = eulerAngles;
  125. }
  126. }
  127. #region Public Methods
  128. public void FocusOnPosition(Vector3 position, float distance = 15f)
  129. {
  130. Vector3 direction = (transform.position - position).normalized;
  131. transform.position = position + direction * distance;
  132. transform.LookAt(position);
  133. }
  134. public void SetPanLimits(Vector2 xLimits, Vector2 zLimits)
  135. {
  136. panLimitX = xLimits;
  137. panLimitZ = zLimits;
  138. }
  139. public void ResetCamera()
  140. {
  141. transform.position = new Vector3(0, 15f, -20f);
  142. transform.rotation = Quaternion.Euler(45f, 0f, 0f);
  143. }
  144. #endregion
  145. private void OnDrawGizmosSelected()
  146. {
  147. // Draw pan limits
  148. Gizmos.color = Color.yellow;
  149. Vector3 center = new Vector3((panLimitX.x + panLimitX.y) / 2f, 0, (panLimitZ.x + panLimitZ.y) / 2f);
  150. Vector3 size = new Vector3(panLimitX.y - panLimitX.x, 1f, panLimitZ.y - panLimitZ.x);
  151. Gizmos.DrawWireCube(center, size);
  152. }
  153. }