using UnityEngine; [RequireComponent(typeof(Camera))] public class MapCameraController : MonoBehaviour { [Header("Настройки карты")] [Tooltip("Ссылка на SpriteRenderer вашей карты для определения границ")] public SpriteRenderer mapRenderer; [Header("Настройки перемещения")] [Tooltip("Скорость перемещения камеры")] public float panSpeed = 15f; [Header("Настройки зума")] [Tooltip("Скорость приближения/отдаления")] public float zoomSpeed = 20f; [Tooltip("Максимальное приближение (минимальный orthographic size)")] public float minZoom = 2f; [Tooltip("Максимальное отдаление (рассчитывается автоматически при старте)")] public float maxZoom = 10f; private Camera cam; private void Awake() { cam = GetComponent(); if (!cam.orthographic) { Debug.LogWarning("Камера должна быть Orthographic (ортографической) для 2D стратегии!"); cam.orthographic = true; } } private void Start() { if (mapRenderer != null) { // Рассчитываем максимальное отдаление так, чтобы камера не могла стать больше самой карты CalculateMaxZoom(); } else { Debug.LogWarning("Не назначен mapRenderer в MapCameraController! Привяжите спрайт карты в инспекторе."); } } private void Update() { HandleZoom(); HandleMovement(); } private void CalculateMaxZoom() { float mapHeight = mapRenderer.bounds.size.y; float mapWidth = mapRenderer.bounds.size.x; // orthographicSize — это половина высоты камеры. // Считаем максимально возможные размеры камеры, чтобы не выходить за границы карты. float maxZoomY = mapHeight / 2f; float maxZoomX = (mapWidth / 2f) / cam.aspect; // Берем минимальное из двух значений, чтобы зум останавливался, когда любая из сторон карты полностью влезает в экран maxZoom = Mathf.Min(maxZoomY, maxZoomX); // Если текущий зум больше возможного, поправляем его cam.orthographicSize = Mathf.Clamp(cam.orthographicSize, minZoom, maxZoom); } private void HandleZoom() { float zoomChange = 0f; // Клавиши приближения (KeypadPlus = Num+, Equals/Plus = обычный +) if (Input.GetKey(KeyCode.KeypadPlus) || Input.GetKey(KeyCode.Equals) || Input.GetKey(KeyCode.Plus)) { zoomChange -= zoomSpeed * Time.deltaTime; } // Клавиши отдаления (KeypadMinus = Num-, Minus = обычный -) if (Input.GetKey(KeyCode.KeypadMinus) || Input.GetKey(KeyCode.Minus)) { zoomChange += zoomSpeed * Time.deltaTime; } // Также добавляем возможность зума на колесико мыши (полезно в стратегиях) float scrollInput = Input.GetAxisRaw("Mouse ScrollWheel"); if (Mathf.Abs(scrollInput) > 0.01f) { zoomChange -= scrollInput * zoomSpeed * 5f; // Умножаем, так как колесико дает маленькие значения } if (Mathf.Abs(zoomChange) > 0.001f) { cam.orthographicSize = Mathf.Clamp(cam.orthographicSize + zoomChange, minZoom, maxZoom); // Если изменился размер экрана, нужно пересчитать центрирование, что сделает функция HandleMovement } } private void HandleMovement() { if (mapRenderer == null) return; // Получаем ввод для осей (по умолчанию в Unity Horizontal — это A, D, LeftArrow, RightArrow; Vertical — W, S, UpArrow, DownArrow) float horizontal = Input.GetAxisRaw("Horizontal"); float vertical = Input.GetAxisRaw("Vertical"); Vector3 moveDirection = new Vector3(horizontal, vertical, 0f).normalized; Vector3 targetPosition = transform.position + moveDirection * panSpeed * Time.deltaTime; // Вычисляем текущие размеры камеры float camHalfHeight = cam.orthographicSize; float camHalfWidth = cam.orthographicSize * cam.aspect; Bounds mapBounds = mapRenderer.bounds; // Вычисляем границы, за которые центр камеры не должен выходить float minX = mapBounds.min.x + camHalfWidth; float maxX = mapBounds.max.x - camHalfWidth; float minY = mapBounds.min.y + camHalfHeight; float maxY = mapBounds.max.y - camHalfHeight; // Ограничиваем позицию по X. // Если карта по ширине уже полностью влезает (minX > maxX), центрируем её if (minX > maxX) { targetPosition.x = mapBounds.center.x; } else { targetPosition.x = Mathf.Clamp(targetPosition.x, minX, maxX); } // Аналогично ограничиваем по Y if (minY > maxY) { targetPosition.y = mapBounds.center.y; } else { targetPosition.y = Mathf.Clamp(targetPosition.y, minY, maxY); } // Применяем позицию (оставляем Z как было) targetPosition.z = transform.position.z; transform.position = targetPosition; } }