| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184 |
- using UnityEngine;
- public class CameraController : MonoBehaviour
- {
- [Header("Movement Settings")]
- [SerializeField] private float panSpeed = 5f;
- [SerializeField] private float zoomSpeed = 2f;
- [SerializeField] private float rotationSpeed = 100f;
- [Header("Limits")]
- [SerializeField] private float minZoom = 5f;
- [SerializeField] private float maxZoom = 50f;
- [SerializeField] private Vector2 panLimitX = new Vector2(-50f, 50f);
- [SerializeField] private Vector2 panLimitZ = new Vector2(-50f, 50f);
- [Header("Input Settings")]
- [SerializeField] private KeyCode panKey = KeyCode.LeftShift;
- [SerializeField] private KeyCode rotateKey = KeyCode.LeftAlt;
- private Camera cam;
- private Vector3 lastMousePosition;
- private bool isDragging = false;
- private void Start()
- {
- cam = GetComponent<Camera>();
- if (cam == null)
- {
- cam = Camera.main;
- }
- // Set initial camera position for hotel view
- transform.position = new Vector3(0, 15f, -20f);
- transform.rotation = Quaternion.Euler(45f, 0f, 0f);
- }
- private void Update()
- {
- HandleMovementInput();
- HandleZoomInput();
- HandleRotationInput();
- }
- private void HandleMovementInput()
- {
- // WASD movement
- Vector3 movement = Vector3.zero;
- if (Input.GetKey(KeyCode.W))
- movement += transform.forward;
- if (Input.GetKey(KeyCode.S))
- movement -= transform.forward;
- if (Input.GetKey(KeyCode.A))
- movement -= transform.right;
- if (Input.GetKey(KeyCode.D))
- movement += transform.right;
- // Apply movement with speed adjustment based on camera height
- float speedMultiplier = transform.position.y / 10f;
- movement *= panSpeed * speedMultiplier * Time.deltaTime;
- // Clamp position within limits
- Vector3 newPosition = transform.position + movement;
- newPosition.x = Mathf.Clamp(newPosition.x, panLimitX.x, panLimitX.y);
- newPosition.z = Mathf.Clamp(newPosition.z, panLimitZ.x, panLimitZ.y);
- transform.position = newPosition;
- // Mouse drag panning
- HandleMousePanning();
- }
- private void HandleMousePanning()
- {
- if (Input.GetMouseButtonDown(2) || (Input.GetMouseButtonDown(0) && Input.GetKey(panKey))) // Middle mouse or Shift+Left mouse
- {
- isDragging = true;
- lastMousePosition = Input.mousePosition;
- }
- else if (Input.GetMouseButtonUp(2) || Input.GetMouseButtonUp(0))
- {
- isDragging = false;
- }
- if (isDragging)
- {
- Vector3 mouseDelta = Input.mousePosition - lastMousePosition;
- // Convert mouse movement to world movement
- Vector3 worldDelta = new Vector3(-mouseDelta.x, 0, -mouseDelta.y) * panSpeed * 0.01f;
- // Apply relative to camera orientation
- worldDelta = transform.TransformDirection(worldDelta);
- worldDelta.y = 0; // Keep camera at same height during panning
- Vector3 newPosition = transform.position + worldDelta;
- newPosition.x = Mathf.Clamp(newPosition.x, panLimitX.x, panLimitX.y);
- newPosition.z = Mathf.Clamp(newPosition.z, panLimitZ.x, panLimitZ.y);
- transform.position = newPosition;
- lastMousePosition = Input.mousePosition;
- }
- }
- private void HandleZoomInput()
- {
- float scroll = Input.GetAxis("Mouse ScrollWheel");
- if (Mathf.Abs(scroll) > 0.01f)
- {
- // For orthographic camera, adjust orthographicSize
- if (cam.orthographic)
- {
- cam.orthographicSize -= scroll * zoomSpeed;
- cam.orthographicSize = Mathf.Clamp(cam.orthographicSize, minZoom, maxZoom);
- }
- else
- {
- // For perspective camera, move camera forward/backward
- Vector3 zoomDirection = transform.forward * scroll * zoomSpeed;
- Vector3 newPosition = transform.position + zoomDirection;
- // Limit zoom by height
- if (newPosition.y >= minZoom && newPosition.y <= maxZoom)
- {
- transform.position = newPosition;
- }
- }
- }
- }
- private void HandleRotationInput()
- {
- if (Input.GetMouseButton(1) || (Input.GetMouseButton(0) && Input.GetKey(rotateKey))) // Right mouse or Alt+Left mouse
- {
- float mouseX = Input.GetAxis("Mouse X") * rotationSpeed * Time.deltaTime;
- float mouseY = -Input.GetAxis("Mouse Y") * rotationSpeed * Time.deltaTime;
- // Rotate around Y axis (horizontal rotation)
- transform.Rotate(Vector3.up, mouseX, Space.World);
- // Rotate around local X axis (vertical rotation)
- transform.Rotate(Vector3.right, mouseY, Space.Self);
- // Clamp vertical rotation
- Vector3 eulerAngles = transform.eulerAngles;
- if (eulerAngles.x > 180f)
- eulerAngles.x -= 360f;
- eulerAngles.x = Mathf.Clamp(eulerAngles.x, -80f, 80f);
- transform.eulerAngles = eulerAngles;
- }
- }
- #region Public Methods
- public void FocusOnPosition(Vector3 position, float distance = 15f)
- {
- Vector3 direction = (transform.position - position).normalized;
- transform.position = position + direction * distance;
- transform.LookAt(position);
- }
- public void SetPanLimits(Vector2 xLimits, Vector2 zLimits)
- {
- panLimitX = xLimits;
- panLimitZ = zLimits;
- }
- public void ResetCamera()
- {
- transform.position = new Vector3(0, 15f, -20f);
- transform.rotation = Quaternion.Euler(45f, 0f, 0f);
- }
- #endregion
- private void OnDrawGizmosSelected()
- {
- // Draw pan limits
- Gizmos.color = Color.yellow;
- Vector3 center = new Vector3((panLimitX.x + panLimitX.y) / 2f, 0, (panLimitZ.x + panLimitZ.y) / 2f);
- Vector3 size = new Vector3(panLimitX.y - panLimitX.x, 1f, panLimitZ.y - panLimitZ.x);
- Gizmos.DrawWireCube(center, size);
- }
- }
|