Initial commit

This commit is contained in:
2026-04-05 12:39:21 +03:00
commit 42e141a7b8
138 changed files with 77433 additions and 0 deletions

View File

@@ -0,0 +1,148 @@
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<Camera>();
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;
}
}