257 lines
8.7 KiB
C#
257 lines
8.7 KiB
C#
using System;
|
||
using System.Collections;
|
||
using System.Collections.Generic;
|
||
using UnityEngine;
|
||
using UnityEngine.EventSystems;
|
||
using RuntimeData;
|
||
using TH1_Logic.Core;
|
||
|
||
public class CameraController : MonoBehaviour
|
||
{
|
||
public float zoomSpeed = 5f; // 滚轮缩放速度
|
||
public float minZoom = 3f; // 最小缩放值
|
||
public float maxZoom = 15f; // 最大缩放值
|
||
public float panSpeed = 0.5f; // 拖动地图的速度
|
||
|
||
|
||
//相机移动上下边界
|
||
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()
|
||
{
|
||
HandleSmoothMove();
|
||
HandleZoom();
|
||
if (Screen.width != _lastWidth || Screen.height != _lastHeight)
|
||
UpdateViewport();
|
||
//if (_camera.orthographic) _camera.orthographicSize = 20f;
|
||
}
|
||
|
||
private void LateUpdate()
|
||
{
|
||
HandlePan();
|
||
}
|
||
|
||
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 (!UIBlockCameraDrag.MoveEvent && _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 CameraMove(Vector3 deltaVector)
|
||
{
|
||
Vector3 targetPosition = Camera.main.transform.position + deltaVector;
|
||
|
||
// 计算当前相机视野的一半宽高
|
||
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;
|
||
}
|
||
void HandlePan()
|
||
{
|
||
if (UIBlockCameraDrag.MoveEvent)
|
||
{
|
||
CameraMove(UIBlockCameraDrag.MoveVector);
|
||
/*Vector3 targetPosition = Camera.main.transform.position + ;
|
||
|
||
// 计算当前相机视野的一半宽高
|
||
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;*/
|
||
UIBlockCameraDrag.DragOrigin = Camera.main.ScreenToWorldPoint(Input.mousePosition);
|
||
}
|
||
else if (Main.Instance.InputLogic!= null && Main.Instance.InputLogic.WASDMapMover)
|
||
{
|
||
Main.Instance.InputLogic.WASDMapMover = false;
|
||
CameraMove(Main.Instance.InputLogic.WASDMapMoverVector);
|
||
}
|
||
}
|
||
|
||
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 = 1400f;
|
||
float boxHeight = 600f;
|
||
|
||
// 削减左侧150像素后的区域
|
||
float reducedLeft = 550f;
|
||
|
||
//如果是AI行动,给画面中心位置
|
||
if (!Main.MapData.CurPlayer?.IsSelfPlayer() ?? false)
|
||
{
|
||
boxWidth = 400f;
|
||
boxHeight = 200f;
|
||
reducedLeft = 0f;
|
||
}
|
||
|
||
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;
|
||
}
|
||
|
||
|
||
|
||
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
} |