226 lines
7.7 KiB
C#
226 lines
7.7 KiB
C#
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using UnityEngine.EventSystems;
|
|
using RuntimeData;
|
|
|
|
public class CameraController : MonoBehaviour
|
|
{
|
|
public float zoomSpeed = 5f; // 滚轮缩放速度
|
|
public float minZoom = 3f; // 最小缩放值
|
|
public float maxZoom = 15f; // 最大缩放值
|
|
public float panSpeed = 0.5f; // 拖动地图的速度
|
|
|
|
//相机拖动相关参数
|
|
private Vector3 _dragOrigin; // 记录拖动起点
|
|
|
|
|
|
//相机移动上下边界
|
|
public float minX = -200f;
|
|
public float maxX = 200f;
|
|
public float minY = -60f;
|
|
public float maxY = 230f;
|
|
|
|
//相机移动动画相关参数
|
|
public float moveSpeed = 0.5f; // 平滑移动速度
|
|
private Vector3? _smoothTargetPosition = null; //记录相机平滑移动的起点
|
|
private Vector3 _startPos;
|
|
private float _moveProgress = 0f;
|
|
private float _moveDuration; // 可调节移动总时长
|
|
private bool _isMoving = false;
|
|
|
|
private const float TARGET_ASPECT = 16f / 9f; // 目标宽高比
|
|
private Camera _camera;
|
|
private int _lastWidth, _lastHeight;
|
|
|
|
void Start()
|
|
{
|
|
_camera = GetComponent<Camera>();
|
|
UpdateViewport();
|
|
}
|
|
|
|
void Update()
|
|
{
|
|
if (UIBlockCameraDrag.ShouldBlockDrag || UIBlockCameraDrag.IsPointerOnUI ) return;
|
|
HandleSmoothMove();
|
|
HandleZoom();
|
|
HandlePan();
|
|
if (Screen.width != _lastWidth || Screen.height != _lastHeight)
|
|
UpdateViewport();
|
|
if (_camera.orthographic) _camera.orthographicSize = 20f;
|
|
}
|
|
|
|
void UpdateViewport()
|
|
{
|
|
float currentAspect = (float)Screen.width / Screen.height;
|
|
Rect rect = new Rect(0, 0, 1, 1); // 默认全屏
|
|
|
|
if (currentAspect > TARGET_ASPECT)
|
|
{
|
|
// 窗口过宽:左右黑边
|
|
rect.width = TARGET_ASPECT / currentAspect;
|
|
rect.x = (1f - rect.width) / 2f;
|
|
}
|
|
else if (currentAspect < TARGET_ASPECT)
|
|
{
|
|
// 窗口过高:上下黑边
|
|
rect.height = currentAspect / TARGET_ASPECT;
|
|
rect.y = (1f - rect.height) / 2f;
|
|
}
|
|
|
|
_camera.rect = rect; // 应用视口矩形
|
|
_lastWidth = Screen.width;
|
|
_lastHeight = Screen.height;
|
|
}
|
|
|
|
void HandleSmoothMove()
|
|
{
|
|
if (_isMoving && _smoothTargetPosition.HasValue)
|
|
{
|
|
_moveProgress += Time.deltaTime / _moveDuration;
|
|
float t = Mathf.SmoothStep(0, 1, _moveProgress); // 缓动曲线
|
|
|
|
Vector3 targetPos = _smoothTargetPosition.Value;
|
|
Camera.main.transform.position = Vector3.Lerp(_startPos, targetPos, t);
|
|
|
|
if (_moveProgress >= 1f)
|
|
{
|
|
Camera.main.transform.position = targetPos;
|
|
_smoothTargetPosition = null;
|
|
_isMoving = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void HandleZoom()
|
|
{
|
|
// 获取滚轮输入
|
|
float scroll = Input.GetAxis("Mouse ScrollWheel");
|
|
if (scroll != 0f)
|
|
{
|
|
Camera.main.orthographicSize -= scroll * zoomSpeed;
|
|
Camera.main.orthographicSize = Mathf.Clamp(Camera.main.orthographicSize, minZoom, maxZoom);
|
|
}
|
|
}
|
|
void HandlePan()
|
|
{
|
|
if (Input.GetMouseButtonDown(0))
|
|
{
|
|
_dragOrigin = Camera.main.ScreenToWorldPoint(Input.mousePosition);
|
|
}
|
|
|
|
|
|
if (Input.GetMouseButton(0))
|
|
{
|
|
Vector3 difference = _dragOrigin - Camera.main.ScreenToWorldPoint(Input.mousePosition);
|
|
Vector3 targetPosition = Camera.main.transform.position + difference;
|
|
|
|
// 计算当前相机视野的一半宽高
|
|
float vertExtent = Camera.main.orthographicSize;
|
|
float horzExtent = vertExtent * Camera.main.aspect;
|
|
|
|
// 限制相机的中心点,使得视野边缘不超出边界
|
|
float minXClamp = minX + horzExtent;
|
|
float maxXClamp = maxX - horzExtent;
|
|
float minYClamp = minY + vertExtent;
|
|
float maxYClamp = maxY - vertExtent;
|
|
|
|
targetPosition.x = Mathf.Clamp(targetPosition.x, minXClamp, maxXClamp);
|
|
targetPosition.y = Mathf.Clamp(targetPosition.y, minYClamp, maxYClamp);
|
|
|
|
Camera.main.transform.position = targetPosition;
|
|
}
|
|
}
|
|
|
|
public void CameraFocusOnGrid(GridData gridData, bool Center = false)
|
|
{
|
|
Vector3 worldPosition = Table.Instance.GridToWorld(gridData);
|
|
float vertExtent = Camera.main.orthographicSize;
|
|
float horzExtent = vertExtent * Camera.main.aspect;
|
|
_moveDuration = Table.Instance.AnimDataAssets.AIAnimCameraMoveTime;
|
|
|
|
//瞬间移到中心
|
|
if (Center)
|
|
{
|
|
float clampedX = Mathf.Clamp(worldPosition.x, minX + horzExtent, maxX - horzExtent);
|
|
float clampedY = Mathf.Clamp(worldPosition.y, minY + vertExtent, maxY - vertExtent);
|
|
Vector3 finalTarget = new Vector3(clampedX, clampedY, Camera.main.transform.position.z);
|
|
|
|
_startPos = Camera.main.transform.position;
|
|
_smoothTargetPosition = finalTarget;
|
|
_moveProgress = 0f;
|
|
_isMoving = true;
|
|
}
|
|
//平滑移动到视觉框内
|
|
else
|
|
{
|
|
Vector3 camPos = Camera.main.transform.position;
|
|
|
|
// 获取世界坐标 → 屏幕坐标
|
|
Vector3 screenPos = Camera.main.WorldToScreenPoint(worldPosition);
|
|
|
|
float screenWidth = Screen.width;
|
|
float screenHeight = Screen.height;
|
|
|
|
// 原始区域尺寸
|
|
float boxWidth = 800f;
|
|
float boxHeight = 500f;
|
|
|
|
// 削减左侧150像素后的区域
|
|
float reducedLeft = 200f;
|
|
float adjustedBoxWidth = boxWidth - reducedLeft;
|
|
|
|
float xMax = (screenWidth + boxWidth) / 2f; // 保持右侧不变
|
|
float xMin = xMax - adjustedBoxWidth; // 左侧往右收缩150像素
|
|
float yMin = (screenHeight - boxHeight) / 2f;
|
|
float yMax = (screenHeight + boxHeight) / 2f;
|
|
|
|
|
|
// 如果点已经在框中,不动
|
|
if (screenPos.x >= xMin && screenPos.x <= xMax &&
|
|
screenPos.y >= yMin && screenPos.y <= yMax)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// 计算目标点应该在屏幕中央框内的“目标屏幕位置”
|
|
float targetScreenX = Mathf.Clamp(screenPos.x, xMin, xMax);
|
|
float targetScreenY = Mathf.Clamp(screenPos.y, yMin, yMax);
|
|
Vector3 desiredScreenPos = new Vector3(targetScreenX, targetScreenY, screenPos.z);
|
|
|
|
// 将这个屏幕位置转回世界空间
|
|
Vector3 desiredWorldPos = Camera.main.ScreenToWorldPoint(desiredScreenPos);
|
|
|
|
// 计算需要相机移动的 delta = 当前格子位置 - 应该出现在的位置
|
|
Vector3 offset = worldPosition - desiredWorldPos;
|
|
Vector3 targetPos = camPos + offset;
|
|
|
|
// 限制相机移动范围
|
|
vertExtent = Camera.main.orthographicSize;
|
|
horzExtent = vertExtent * Camera.main.aspect;
|
|
float minXClamp = minX + horzExtent;
|
|
float maxXClamp = maxX - horzExtent;
|
|
float minYClamp = minY + vertExtent;
|
|
float maxYClamp = maxY - vertExtent;
|
|
|
|
targetPos.x = Mathf.Clamp(targetPos.x, minXClamp, maxXClamp);
|
|
targetPos.y = Mathf.Clamp(targetPos.y, minYClamp, maxYClamp);
|
|
|
|
// 平滑移动
|
|
_startPos = camPos;
|
|
_smoothTargetPosition = new Vector3(targetPos.x, targetPos.y, camPos.z);
|
|
_moveProgress = 0f;
|
|
_isMoving = true;
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
} |