2025-04-29 15:30:55 +08:00
|
|
|
|
using System;
|
|
|
|
|
|
using DG.Tweening;
|
2025-04-29 13:16:40 +08:00
|
|
|
|
using Framework;
|
2025-05-19 19:01:02 +08:00
|
|
|
|
using PhxhSDK;
|
2025-04-28 15:26:51 +08:00
|
|
|
|
using UnityEngine;
|
2025-04-29 15:30:55 +08:00
|
|
|
|
using Sirenix.OdinInspector;
|
2025-04-29 13:16:40 +08:00
|
|
|
|
using UnityEngine.EventSystems;
|
2025-04-28 15:26:51 +08:00
|
|
|
|
|
|
|
|
|
|
[ExecuteAlways]
|
|
|
|
|
|
public class CameraController : MonoBehaviour
|
|
|
|
|
|
{
|
2025-04-29 15:30:55 +08:00
|
|
|
|
private const float CameraStartY = 25;
|
|
|
|
|
|
private const float CameraStartSize = 12;
|
|
|
|
|
|
private float CameraStartFOV = 30;
|
|
|
|
|
|
private const float NearClipPlane = 0.03f;
|
|
|
|
|
|
private const float FarClipPlane = 150;
|
2025-06-10 16:31:09 +08:00
|
|
|
|
private float _lastFOV = 30;
|
2025-06-12 14:45:49 +08:00
|
|
|
|
private Vector3 _lastPos = new Vector3(0, 0, 0);
|
2025-04-29 15:30:55 +08:00
|
|
|
|
private readonly Vector3 cameraStartRotationO = new Vector3(37.5f, -10f, 0f);
|
2025-04-28 15:26:51 +08:00
|
|
|
|
|
2025-04-29 15:30:55 +08:00
|
|
|
|
private readonly Vector3 cameraStartRotationP = new Vector3(45, -10, 0);
|
2025-04-28 15:26:51 +08:00
|
|
|
|
|
2025-04-29 15:30:55 +08:00
|
|
|
|
//之前的缩放是6次滚轮从最小放到最大,故每一次缩放的值为1/6f
|
|
|
|
|
|
private const float ZoomStep = 1 / 12f;
|
|
|
|
|
|
|
|
|
|
|
|
[Tooltip("控制缩放响应曲线")] public float zoomSensitivity = 2.0f;
|
|
|
|
|
|
[Tooltip("缩放速度与当前缩放比例的关系系数")] public float zoomScaleFactor = 0.75f;
|
|
|
|
|
|
[Tooltip("是否使用平滑缩放效果")] public bool smoothZoom = true;
|
|
|
|
|
|
[ShowIf("smoothZoom")] public float zoomSmoothTime = 0.2f;
|
|
|
|
|
|
|
|
|
|
|
|
public float leftMargin = 1.5f;
|
|
|
|
|
|
|
|
|
|
|
|
public float rightMargin = 1.5f;
|
|
|
|
|
|
|
|
|
|
|
|
public float topMargin = 0.9f;
|
|
|
|
|
|
|
|
|
|
|
|
public float bottomMargin = 0.9f;
|
|
|
|
|
|
|
|
|
|
|
|
[Header("Camera Movement Settings")] public float moveSpeedX = 0.19f;
|
|
|
|
|
|
public float moveSpeedY = 0.3f;
|
|
|
|
|
|
public float unitPerPixel = 0.01f;
|
|
|
|
|
|
|
|
|
|
|
|
[Tooltip("是否使用平滑移动效果")] public bool smoothPanning = false;
|
|
|
|
|
|
|
|
|
|
|
|
[ShowIf("smoothPanning")] [Tooltip("平移平滑时间,值越小响应越快")]
|
|
|
|
|
|
public float panSmoothTime = 0.08f;
|
|
|
|
|
|
|
|
|
|
|
|
[ShowIf("smoothPanning")] [Tooltip("惯性系数,控制释放后继续滑动的距离")] [Range(0, 1)]
|
|
|
|
|
|
public float panInertia = 0.8f;
|
|
|
|
|
|
|
|
|
|
|
|
[ShowIf("smoothPanning")] [Tooltip("最大平移速度限制")]
|
|
|
|
|
|
public float maxPanSpeed = 3000f;
|
|
|
|
|
|
|
|
|
|
|
|
public float CameraMinSize = 6;
|
|
|
|
|
|
public float CameraMaxSize = 12;
|
|
|
|
|
|
public BoxCollider boxBounds;
|
|
|
|
|
|
public float CameraMinFOV = 15;
|
|
|
|
|
|
public float CameraMaxFOV = 30;
|
2025-05-19 19:01:02 +08:00
|
|
|
|
private bool _isScaleChange;
|
2025-04-29 15:30:55 +08:00
|
|
|
|
|
|
|
|
|
|
private Camera mainCamera;
|
|
|
|
|
|
|
|
|
|
|
|
public Camera MainCamera
|
|
|
|
|
|
{
|
|
|
|
|
|
get { return mainCamera; }
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private bool isIgnoreZoomLimit;
|
|
|
|
|
|
|
|
|
|
|
|
public Bounds CameraBounds { get; set; }
|
|
|
|
|
|
|
|
|
|
|
|
private bool isOrthographic => mainCamera.orthographic;
|
|
|
|
|
|
|
|
|
|
|
|
//Camera拖动控制
|
|
|
|
|
|
public static bool FingerMoveEnable = true;
|
|
|
|
|
|
|
|
|
|
|
|
private float targetZoomScale;
|
|
|
|
|
|
private float zoomVelocity;
|
|
|
|
|
|
|
|
|
|
|
|
private Vector3 targetPanPosition;
|
|
|
|
|
|
private Vector3 panVelocity;
|
|
|
|
|
|
private Vector2 lastDragDelta;
|
|
|
|
|
|
private float lastDragTime;
|
|
|
|
|
|
|
|
|
|
|
|
//size,将透视和正交相机的fov和orthographic size整合为统一数值
|
|
|
|
|
|
private float Size
|
|
|
|
|
|
{
|
|
|
|
|
|
get
|
|
|
|
|
|
{
|
|
|
|
|
|
if (isOrthographic)
|
|
|
|
|
|
return mainCamera.orthographicSize;
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
var fov = mainCamera.fieldOfView;
|
|
|
|
|
|
//这里乘(CameraMaxSize - CameraMinSize)/(CameraMaxFOV - CameraMinFOV)是将fov的区间变得和orthographic size区间一致
|
|
|
|
|
|
return fov * (CameraMaxSize - CameraMinSize) / (CameraMaxFOV - CameraMinFOV);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//缩放百分比,0表示放到最小,1表示放到最大
|
|
|
|
|
|
private float ZoomScale
|
|
|
|
|
|
{
|
|
|
|
|
|
get
|
|
|
|
|
|
{
|
|
|
|
|
|
if (isOrthographic)
|
|
|
|
|
|
return (CameraMaxSize - mainCamera.orthographicSize) / (CameraMaxSize - CameraMinSize);
|
|
|
|
|
|
else
|
|
|
|
|
|
return (CameraMaxFOV - mainCamera.fieldOfView) / (CameraMaxFOV - CameraMinFOV);
|
|
|
|
|
|
}
|
|
|
|
|
|
set
|
|
|
|
|
|
{
|
|
|
|
|
|
var t = Mathf.Clamp(value, 0, 1);
|
|
|
|
|
|
if (Math.Abs(ZoomScale - t) < float.Epsilon)
|
|
|
|
|
|
return;
|
|
|
|
|
|
if (isOrthographic)
|
|
|
|
|
|
mainCamera.orthographicSize = Mathf.Lerp(CameraMaxSize, CameraMinSize, t);
|
|
|
|
|
|
else
|
|
|
|
|
|
mainCamera.fieldOfView = Mathf.Lerp(CameraMaxFOV, CameraMinFOV, t);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-04-28 15:26:51 +08:00
|
|
|
|
|
|
|
|
|
|
private void Awake()
|
|
|
|
|
|
{
|
2025-08-11 18:26:11 +08:00
|
|
|
|
if (BusyWrapper.isBusy)
|
|
|
|
|
|
return;
|
2025-04-29 15:30:55 +08:00
|
|
|
|
mainCamera = GetComponent<Camera>();
|
|
|
|
|
|
targetZoomScale = ZoomScale;
|
|
|
|
|
|
targetPanPosition = transform.position;
|
|
|
|
|
|
|
2025-05-08 12:36:01 +08:00
|
|
|
|
var useOrthographic = Application.isPlaying && CameraServiceLocator.CameraService.UseOrthographicMode;
|
2025-04-28 15:26:51 +08:00
|
|
|
|
|
2025-04-29 15:30:55 +08:00
|
|
|
|
if (useOrthographic)
|
|
|
|
|
|
{
|
|
|
|
|
|
mainCamera.orthographic = true;
|
|
|
|
|
|
mainCamera.orthographicSize = CameraStartSize;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
2025-04-28 15:26:51 +08:00
|
|
|
|
{
|
2025-04-29 15:30:55 +08:00
|
|
|
|
mainCamera.orthographic = false;
|
|
|
|
|
|
mainCamera.fieldOfView = CameraStartFOV;
|
2025-04-28 15:26:51 +08:00
|
|
|
|
}
|
2025-04-29 15:30:55 +08:00
|
|
|
|
|
|
|
|
|
|
mainCamera.nearClipPlane = NearClipPlane;
|
|
|
|
|
|
mainCamera.farClipPlane = FarClipPlane;
|
|
|
|
|
|
CameraBounds = boxBounds != null ? boxBounds.bounds : CameraBounds;
|
|
|
|
|
|
|
|
|
|
|
|
AdjustSelf();
|
2025-04-28 15:26:51 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void OnEnable()
|
|
|
|
|
|
{
|
2025-08-11 18:26:11 +08:00
|
|
|
|
if (BusyWrapper.isBusy)
|
|
|
|
|
|
return;
|
2025-04-29 13:16:40 +08:00
|
|
|
|
if (Application.isPlaying)
|
2025-04-28 15:26:51 +08:00
|
|
|
|
{
|
2025-04-29 13:16:40 +08:00
|
|
|
|
//InputManager.Instance.OnFingerMove += OnFingerMove2;
|
|
|
|
|
|
EventManager.Instance.Register<PointerEventData>(EventManager.EventName.Level_OnDrag, _OnDragMove);
|
2025-04-29 15:30:55 +08:00
|
|
|
|
EventManager.Instance.Register<PointerEventData>(EventManager.EventName.Level_OnEndDrag, OnEndDrag);
|
|
|
|
|
|
InputManager.Instance.OnFingersMove += OnFingersMove;
|
2025-05-19 19:01:02 +08:00
|
|
|
|
InputManager.Instance.OnFingerUp += _OnFingerUp;
|
2025-04-28 15:26:51 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void OnDisable()
|
|
|
|
|
|
{
|
2025-08-11 18:26:11 +08:00
|
|
|
|
if (BusyWrapper.isBusy)
|
|
|
|
|
|
return;
|
2025-04-29 13:16:40 +08:00
|
|
|
|
if (Application.isPlaying)
|
2025-04-28 15:26:51 +08:00
|
|
|
|
{
|
2025-04-29 13:16:40 +08:00
|
|
|
|
if (InputManager.Instance == null) return;
|
2025-04-29 15:30:55 +08:00
|
|
|
|
//InputManager.Instance.OnFingerMove -= OnFingerMove2;
|
|
|
|
|
|
EventManager.Instance.Unregister<PointerEventData>(EventManager.EventName.Level_OnDrag, _OnDragMove);
|
|
|
|
|
|
EventManager.Instance.Unregister<PointerEventData>(EventManager.EventName.Level_OnEndDrag, OnEndDrag);
|
|
|
|
|
|
InputManager.Instance.OnFingersMove -= OnFingersMove;
|
2025-05-19 19:01:02 +08:00
|
|
|
|
InputManager.Instance.OnFingerUp -= _OnFingerUp;
|
2025-04-28 15:26:51 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-04-29 15:30:55 +08:00
|
|
|
|
private void _OnDragMove(PointerEventData pointerData)
|
2025-04-28 15:26:51 +08:00
|
|
|
|
{
|
2025-04-29 15:30:55 +08:00
|
|
|
|
if (!FingerMoveEnable)
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
Vector3 newPosition;
|
|
|
|
|
|
var startPos = pointerData.pressPosition;
|
|
|
|
|
|
var delta = pointerData.delta;
|
|
|
|
|
|
|
|
|
|
|
|
// 记录拖动速度数据,用于惯性计算
|
|
|
|
|
|
lastDragDelta = delta;
|
|
|
|
|
|
lastDragTime = Time.time;
|
|
|
|
|
|
|
2025-05-19 19:01:02 +08:00
|
|
|
|
CameraManager.IsMainCameraMoving = true;
|
2025-04-29 15:30:55 +08:00
|
|
|
|
var oldRay = mainCamera.ScreenPointToRay(startPos);
|
|
|
|
|
|
var newRay = mainCamera.ScreenPointToRay(startPos + delta);
|
|
|
|
|
|
var layerMask = 1 << LayerMask.NameToLayer("Ground");
|
|
|
|
|
|
|
|
|
|
|
|
if (Physics.Raycast(oldRay, out var oldHit, 1000, layerMask) &&
|
|
|
|
|
|
Physics.Raycast(newRay, out var newHit, 1000, layerMask))
|
2025-04-28 15:26:51 +08:00
|
|
|
|
{
|
2025-04-29 15:30:55 +08:00
|
|
|
|
var offset = oldHit.point - newHit.point;
|
|
|
|
|
|
|
|
|
|
|
|
if (smoothPanning)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 在平滑模式下设置目标位置
|
|
|
|
|
|
targetPanPosition = transform.position + offset;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
// 立即移动
|
|
|
|
|
|
transform.Translate(offset, Space.World);
|
|
|
|
|
|
AdjustSelf();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
Vector2 touchDeltaPosition = -delta;
|
|
|
|
|
|
float ratio = Size * unitPerPixel;
|
|
|
|
|
|
Vector2 cameraMove = new(touchDeltaPosition.x * moveSpeedX * ratio,
|
|
|
|
|
|
touchDeltaPosition.y * moveSpeedY * ratio);
|
|
|
|
|
|
|
|
|
|
|
|
var cameraTransform = transform;
|
|
|
|
|
|
var moveY = cameraTransform.up;
|
|
|
|
|
|
moveY.y = 0;
|
|
|
|
|
|
moveY = moveY.normalized * cameraMove.y;
|
|
|
|
|
|
|
|
|
|
|
|
var moveX = cameraTransform.right;
|
|
|
|
|
|
moveX.y = 0;
|
|
|
|
|
|
moveX = moveX.normalized * cameraMove.x;
|
|
|
|
|
|
|
|
|
|
|
|
if (smoothPanning)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 在平滑模式下设置目标位置
|
|
|
|
|
|
targetPanPosition = transform.position + moveX + moveY;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
// 立即移动
|
|
|
|
|
|
transform.Translate(moveX + moveY, Space.World);
|
|
|
|
|
|
AdjustSelf();
|
|
|
|
|
|
}
|
2025-04-28 15:26:51 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-04-29 15:30:55 +08:00
|
|
|
|
// 处理拖动结束时的惯性
|
|
|
|
|
|
public void OnEndDrag(PointerEventData pointerData)
|
2025-04-28 15:26:51 +08:00
|
|
|
|
{
|
2025-04-29 15:30:55 +08:00
|
|
|
|
if (smoothPanning && panInertia > 0 && Time.time - lastDragTime < 0.1f)
|
2025-04-28 15:26:51 +08:00
|
|
|
|
{
|
2025-04-29 15:30:55 +08:00
|
|
|
|
// 计算惯性位移
|
|
|
|
|
|
Vector2 touchDeltaPosition = -lastDragDelta * panInertia;
|
|
|
|
|
|
float ratio = Size * unitPerPixel;
|
|
|
|
|
|
Vector2 inertiaMove = new(touchDeltaPosition.x * moveSpeedX * ratio,
|
|
|
|
|
|
touchDeltaPosition.y * moveSpeedY * ratio);
|
|
|
|
|
|
|
|
|
|
|
|
var cameraTransform = transform;
|
|
|
|
|
|
var moveY = cameraTransform.up;
|
|
|
|
|
|
moveY.y = 0;
|
|
|
|
|
|
moveY = moveY.normalized * inertiaMove.y;
|
|
|
|
|
|
|
|
|
|
|
|
var moveX = cameraTransform.right;
|
|
|
|
|
|
moveX.y = 0;
|
|
|
|
|
|
moveX = moveX.normalized * inertiaMove.x;
|
|
|
|
|
|
|
|
|
|
|
|
// 应用惯性
|
|
|
|
|
|
targetPanPosition += moveX + moveY;
|
2025-04-28 15:26:51 +08:00
|
|
|
|
}
|
2025-05-19 19:01:02 +08:00
|
|
|
|
|
|
|
|
|
|
CameraManager.IsMainCameraMoving = false;
|
2025-04-28 15:26:51 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-04-29 15:30:55 +08:00
|
|
|
|
private void OnFingersMove(float delta)
|
2025-04-29 13:16:40 +08:00
|
|
|
|
{
|
2025-04-29 15:30:55 +08:00
|
|
|
|
if (!FingerMoveEnable)
|
|
|
|
|
|
{
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (CameraServiceLocator.CameraService.IsGuiding) // 引导中禁止缩放
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
// 缩放系数随当前缩放程度变化,缩放越小,缩放速度越慢,提供更精确的控制
|
|
|
|
|
|
float currentZoomFactor = ZoomStep * zoomSensitivity;
|
|
|
|
|
|
|
2025-05-19 19:01:02 +08:00
|
|
|
|
CameraManager.IsMainCameraMoving = true;
|
2025-07-10 14:59:35 +08:00
|
|
|
|
// DebugUtil.LogP($"OnFingersMove");
|
2025-05-19 19:01:02 +08:00
|
|
|
|
|
2025-04-29 15:30:55 +08:00
|
|
|
|
// 根据当前缩放比例调整缩放速度
|
|
|
|
|
|
if (zoomScaleFactor > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
float scaleModifier = Mathf.Lerp(0.5f, 1.5f, ZoomScale * zoomScaleFactor);
|
|
|
|
|
|
currentZoomFactor *= scaleModifier;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//delta小于0是缩小
|
|
|
|
|
|
var zoomDelta = delta < 0 ? -currentZoomFactor : currentZoomFactor;
|
|
|
|
|
|
|
|
|
|
|
|
//修改目标缩放值
|
2025-05-19 19:01:02 +08:00
|
|
|
|
_isScaleChange = true;
|
2025-04-29 15:30:55 +08:00
|
|
|
|
if (smoothZoom)
|
|
|
|
|
|
{
|
|
|
|
|
|
targetZoomScale = Mathf.Clamp01(targetZoomScale + zoomDelta);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
//直接缩放,无平滑效果
|
|
|
|
|
|
ZoomScale += zoomDelta;
|
|
|
|
|
|
AdjustSelf();
|
|
|
|
|
|
}
|
2025-04-29 13:16:40 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-05-19 19:01:02 +08:00
|
|
|
|
private void _OnFingerUp(Vector2 screenPos)
|
|
|
|
|
|
{
|
|
|
|
|
|
CameraManager.IsMainCameraMoving = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-08-14 12:57:43 +08:00
|
|
|
|
private void LateUpdate()
|
2025-04-29 13:16:40 +08:00
|
|
|
|
{
|
2025-08-11 18:26:11 +08:00
|
|
|
|
if (BusyWrapper.isBusy)
|
|
|
|
|
|
return;
|
2025-04-29 15:30:55 +08:00
|
|
|
|
// 处理平滑缩放
|
2025-05-19 19:01:02 +08:00
|
|
|
|
bool isScaled = Math.Abs(ZoomScale - targetZoomScale) > 0.01f;
|
2025-06-10 16:31:09 +08:00
|
|
|
|
bool isFovChange = Math.Abs(_lastFOV - mainCamera.fieldOfView) > 0.01f;
|
2025-05-19 19:01:02 +08:00
|
|
|
|
if (smoothZoom && isScaled)
|
2025-04-29 15:30:55 +08:00
|
|
|
|
{
|
|
|
|
|
|
// 使用SmoothDamp实现平滑缩放效果
|
|
|
|
|
|
float newZoomScale = Mathf.SmoothDamp(ZoomScale, targetZoomScale, ref zoomVelocity, zoomSmoothTime);
|
|
|
|
|
|
ZoomScale = newZoomScale;
|
|
|
|
|
|
AdjustSelf();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 处理平滑平移
|
|
|
|
|
|
if (smoothPanning && Vector3.Distance(transform.position, targetPanPosition) > 0.01f)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 限制最大速度
|
|
|
|
|
|
Vector3 newPosition = Vector3.SmoothDamp(transform.position, targetPanPosition,
|
|
|
|
|
|
ref panVelocity, panSmoothTime, maxPanSpeed);
|
|
|
|
|
|
transform.position = newPosition;
|
|
|
|
|
|
AdjustSelf();
|
|
|
|
|
|
}
|
2025-05-19 19:01:02 +08:00
|
|
|
|
|
2025-06-12 14:45:49 +08:00
|
|
|
|
if (_lastPos != mainCamera.transform.position)
|
|
|
|
|
|
{
|
|
|
|
|
|
_lastPos = mainCamera.transform.position;
|
|
|
|
|
|
CameraManager.IsMainCameraMoving = true;
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
CameraManager.IsMainCameraMoving = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (_isScaleChange && !isScaled)
|
|
|
|
|
|
{
|
|
|
|
|
|
//DebugUtil.LogP($"--- Update _isScaleChange:{_isScaleChange}, isScaled{isScaled}");
|
|
|
|
|
|
CameraManager.IsMainCameraMoving = false;
|
|
|
|
|
|
_isScaleChange = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (isFovChange)
|
2025-05-19 19:01:02 +08:00
|
|
|
|
{
|
2025-06-10 16:43:27 +08:00
|
|
|
|
_lastFOV = mainCamera.fieldOfView;
|
|
|
|
|
|
// DebugUtil.LogP($"--- Update _isScaleChange:{_isScaleChange}, isScaled{isScaled}");
|
|
|
|
|
|
// DebugUtil.LogP($"==== Update isFovChange, isScaled{isScaled}");
|
|
|
|
|
|
CameraManager.IsMainCameraMoving = true;
|
2025-08-14 12:57:43 +08:00
|
|
|
|
|
|
|
|
|
|
EventManager.Instance.Send(EventManager.EventName.Camera_FovChanged);
|
2025-06-10 16:43:27 +08:00
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
2025-05-19 19:01:02 +08:00
|
|
|
|
CameraManager.IsMainCameraMoving = false;
|
|
|
|
|
|
}
|
2025-04-29 13:16:40 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-04-29 15:30:55 +08:00
|
|
|
|
public void KeepCenter(Vector3 centerPos)
|
2025-04-29 13:16:40 +08:00
|
|
|
|
{
|
2025-04-29 15:30:55 +08:00
|
|
|
|
var cacheTrans = mainCamera.transform;
|
|
|
|
|
|
var oldPos = cacheTrans.position;
|
|
|
|
|
|
oldPos.x = centerPos.x - 5f;
|
|
|
|
|
|
oldPos.z = centerPos.z - 25f;
|
|
|
|
|
|
// cacheTrans.position = oldPos;
|
2025-05-19 19:01:02 +08:00
|
|
|
|
CameraManager.IsMainCameraMoving = true;
|
|
|
|
|
|
cacheTrans.DOMove(oldPos, 0.3f).OnUpdate(AdjustSelf).OnComplete(() =>
|
|
|
|
|
|
{
|
|
|
|
|
|
CameraManager.IsMainCameraMoving = false;
|
|
|
|
|
|
});
|
2025-04-29 13:16:40 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-04-29 15:30:55 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 营地相机保持中心位置
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="centerPos"></param>
|
|
|
|
|
|
public void CampKeepCenter(Vector3 centerPos)
|
|
|
|
|
|
{
|
|
|
|
|
|
Transform cacheTrans = mainCamera.transform;
|
|
|
|
|
|
Vector3 newPos = cacheTrans.position;
|
|
|
|
|
|
newPos.x = centerPos.x + 17.5f;
|
|
|
|
|
|
newPos.z = centerPos.z + 30.5f;
|
2025-04-28 15:26:51 +08:00
|
|
|
|
|
2025-07-24 13:32:22 +08:00
|
|
|
|
cacheTrans.DOMove(newPos, 0.3f).OnUpdate(AdjustSelf);//.OnComplete(() => { targetZoomScale = 1f; });
|
|
|
|
|
|
targetZoomScale = 1f;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 营地还原相机fov
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public void CampRevertFov()
|
|
|
|
|
|
{
|
|
|
|
|
|
targetZoomScale = 0f;
|
2025-04-29 15:30:55 +08:00
|
|
|
|
}
|
2025-04-28 15:26:51 +08:00
|
|
|
|
|
2025-04-29 15:30:55 +08:00
|
|
|
|
Vector3 CalculateHitHorizontalPosition(Vector3 startPosition, Vector3 dir, float y)
|
2025-04-28 15:26:51 +08:00
|
|
|
|
{
|
2025-04-29 15:30:55 +08:00
|
|
|
|
if (dir.y == 0)
|
|
|
|
|
|
return Vector3.zero;
|
|
|
|
|
|
|
|
|
|
|
|
var p1 = startPosition; // 直线上一点
|
|
|
|
|
|
var v = dir; // 直线的方向向量
|
|
|
|
|
|
float x, z;
|
|
|
|
|
|
|
|
|
|
|
|
// 已知直线上一点 p1(x1, y1, z1) 和 直线的方向向量 v(m, n, p)
|
|
|
|
|
|
// 根据点向式
|
|
|
|
|
|
// (x - x1) / m = (y - y1) / n = (z - z1) / p
|
|
|
|
|
|
// 有:
|
|
|
|
|
|
// (x - p1.x) / v.x = (y - p1.y) / v.y = (z - p1.z) / v.z
|
|
|
|
|
|
// 有:
|
|
|
|
|
|
// x = p1.x + v.x * (y - p1.y) / v.y
|
|
|
|
|
|
// z = p1.z + v.z * (y - p1.y) / v.y
|
|
|
|
|
|
// 与平面 y = y 的交点坐标为
|
|
|
|
|
|
|
|
|
|
|
|
x = p1.x + v.x * (y - p1.y) / v.y;
|
|
|
|
|
|
z = p1.z + v.z * (y - p1.y) / v.y;
|
|
|
|
|
|
return new Vector3(x, y, z);
|
2025-04-28 15:26:51 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-04-29 15:30:55 +08:00
|
|
|
|
public void InitializeCameraPosition(Vector3 targetPosition, MapData.CameraInfo cameraInfo = null)
|
2025-04-28 15:26:51 +08:00
|
|
|
|
{
|
2025-05-08 12:36:01 +08:00
|
|
|
|
var useOrthographic = Application.isPlaying && CameraServiceLocator.CameraService.UseOrthographicMode;
|
2025-04-29 15:30:55 +08:00
|
|
|
|
mainCamera.transform.position = CalculateCell2CameraPosition(targetPosition);
|
|
|
|
|
|
|
|
|
|
|
|
// 进入关卡初始化相机
|
|
|
|
|
|
if (cameraInfo != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
rightMargin = cameraInfo.rightMarginInPre;
|
|
|
|
|
|
leftMargin = cameraInfo.leftMarginInPre;
|
|
|
|
|
|
topMargin = cameraInfo.topMarginInInPre;
|
|
|
|
|
|
bottomMargin = cameraInfo.bottomMarginInPre;
|
|
|
|
|
|
SetCameraFOVSize(cameraInfo.initialFOV);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var rotEuler = useOrthographic ? cameraStartRotationO : cameraStartRotationP;
|
|
|
|
|
|
// 修改为支持修改相机角度
|
|
|
|
|
|
/*mainCamera.transform.SetPositionAndRotation(
|
|
|
|
|
|
CalculateCell2CameraPosition(targetPosition), Quaternion.Euler(rotEuler));*/
|
|
|
|
|
|
AdjustSelf();
|
2025-04-28 15:26:51 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-04-29 15:30:55 +08:00
|
|
|
|
private Vector3 CalculateCell2CameraPosition(Vector3 targetPosition)
|
2025-04-28 15:26:51 +08:00
|
|
|
|
{
|
2025-04-29 15:30:55 +08:00
|
|
|
|
var cameraTransform = mainCamera.transform;
|
|
|
|
|
|
var startPosition = cameraTransform.position;
|
|
|
|
|
|
var v = cameraTransform.forward;
|
|
|
|
|
|
|
|
|
|
|
|
float x, z;
|
|
|
|
|
|
z = targetPosition.z - v.z * (targetPosition.y - startPosition.y) / v.y;
|
|
|
|
|
|
x = targetPosition.x - v.x * (targetPosition.y - startPosition.y) / v.y;
|
|
|
|
|
|
|
|
|
|
|
|
return new Vector3(x, startPosition.y, z);
|
2025-04-28 15:26:51 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void AdjustSelf()
|
|
|
|
|
|
{
|
2025-04-29 15:30:55 +08:00
|
|
|
|
mainCamera.transform.position = AdjustPosition(Size, out var isInsideBounds);
|
2025-04-28 15:26:51 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void SetCameraFOVSize(float initialFOV)
|
|
|
|
|
|
{
|
2025-04-29 15:30:55 +08:00
|
|
|
|
if (mainCamera == null) return;
|
|
|
|
|
|
var fov = Mathf.Clamp(initialFOV, CameraMinFOV, CameraMaxFOV);
|
|
|
|
|
|
if (!mainCamera.orthographic)
|
|
|
|
|
|
{
|
|
|
|
|
|
CameraStartFOV = fov;
|
|
|
|
|
|
mainCamera.fieldOfView = fov;
|
|
|
|
|
|
targetZoomScale = ZoomScale;
|
|
|
|
|
|
}
|
2025-04-28 15:26:51 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-04-29 15:30:55 +08:00
|
|
|
|
private Vector3 _startPos;
|
|
|
|
|
|
private float _cacheZoomScale;
|
|
|
|
|
|
|
2025-04-28 15:26:51 +08:00
|
|
|
|
public void RecordStartPos()
|
|
|
|
|
|
{
|
2025-04-29 15:30:55 +08:00
|
|
|
|
_startPos = mainCamera.transform.position;
|
|
|
|
|
|
_cacheZoomScale = targetZoomScale;
|
2025-04-28 15:26:51 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void ResetToStartPos(float during = 0.3f)
|
|
|
|
|
|
{
|
2025-04-29 15:30:55 +08:00
|
|
|
|
if (mainCamera == null) return;
|
|
|
|
|
|
targetZoomScale = _cacheZoomScale;
|
|
|
|
|
|
mainCamera.transform.DOMove(_startPos, during).OnUpdate(AdjustSelf);
|
|
|
|
|
|
// .OnComplete(() => { targetZoomScale = 1f; });
|
2025-04-28 15:26:51 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-04-29 15:30:55 +08:00
|
|
|
|
private Vector3 AdjustPosition(float size, out bool IsInsideBounds)
|
|
|
|
|
|
{
|
|
|
|
|
|
var position = transform.position;
|
|
|
|
|
|
IsInsideBounds = true;
|
2025-04-28 15:26:51 +08:00
|
|
|
|
|
2025-04-29 15:30:55 +08:00
|
|
|
|
var center = CalculateHitHorizontalPosition(position, transform.forward, 0);
|
|
|
|
|
|
var left = center.x - leftMargin * size;
|
|
|
|
|
|
var right = center.x + rightMargin * size;
|
|
|
|
|
|
var top = center.z + topMargin * size;
|
|
|
|
|
|
var bottom = center.z - bottomMargin * size;
|
2025-04-28 15:26:51 +08:00
|
|
|
|
|
2025-04-29 15:30:55 +08:00
|
|
|
|
if (right - left < CameraBounds.max.x - CameraBounds.min.x)
|
2025-04-28 15:26:51 +08:00
|
|
|
|
{
|
2025-04-29 15:30:55 +08:00
|
|
|
|
if (left < CameraBounds.min.x)
|
|
|
|
|
|
{
|
|
|
|
|
|
center.x = CameraBounds.min.x + leftMargin * size;
|
|
|
|
|
|
IsInsideBounds = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (right > CameraBounds.max.x)
|
|
|
|
|
|
{
|
|
|
|
|
|
center.x = CameraBounds.max.x - rightMargin * size;
|
|
|
|
|
|
IsInsideBounds = false;
|
|
|
|
|
|
}
|
2025-04-28 15:26:51 +08:00
|
|
|
|
}
|
2025-04-29 15:30:55 +08:00
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
center.x = CameraBounds.center.x;
|
|
|
|
|
|
IsInsideBounds = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (top - bottom < CameraBounds.max.z - CameraBounds.min.z)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (bottom < CameraBounds.min.z)
|
|
|
|
|
|
{
|
|
|
|
|
|
center.z = CameraBounds.min.z + bottomMargin * size;
|
|
|
|
|
|
IsInsideBounds = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (top > CameraBounds.max.z)
|
|
|
|
|
|
{
|
|
|
|
|
|
center.z = CameraBounds.max.z - topMargin * size;
|
|
|
|
|
|
IsInsideBounds = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
center.z = CameraBounds.center.z;
|
|
|
|
|
|
IsInsideBounds = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
position = CalculateHitHorizontalPosition(center, transform.forward, position.y);
|
|
|
|
|
|
return position;
|
2025-04-28 15:26:51 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-04-29 15:30:55 +08:00
|
|
|
|
private void OnDrawGizmos()
|
|
|
|
|
|
{
|
2025-08-11 18:26:11 +08:00
|
|
|
|
if (BusyWrapper.isBusy)
|
|
|
|
|
|
return;
|
2025-04-29 15:30:55 +08:00
|
|
|
|
if (mainCamera != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
Gizmos.color = Color.red;
|
|
|
|
|
|
var cameraTransform = transform;
|
|
|
|
|
|
var position = cameraTransform.position;
|
|
|
|
|
|
var size = Size;
|
|
|
|
|
|
var center = CalculateHitHorizontalPosition(position, cameraTransform.forward, 0);
|
|
|
|
|
|
var left = center.x - leftMargin * size;
|
|
|
|
|
|
var right = center.x + rightMargin * size;
|
|
|
|
|
|
var top = center.z + topMargin * size;
|
|
|
|
|
|
var bottom = center.z - bottomMargin * size;
|
|
|
|
|
|
|
|
|
|
|
|
Gizmos.DrawLineList(new ReadOnlySpan<Vector3>(new[]
|
|
|
|
|
|
{
|
|
|
|
|
|
new Vector3(left, 0.5f, top), new Vector3(left, 0.5f, bottom),
|
|
|
|
|
|
new Vector3(left, 0.5f, bottom), new Vector3(right, 0.5f, bottom),
|
|
|
|
|
|
new Vector3(right, 0.5f, bottom), new Vector3(right, 0.5f, top),
|
|
|
|
|
|
new Vector3(right, 0.5f, top), new Vector3(left, 0.5f, top),
|
|
|
|
|
|
}
|
|
|
|
|
|
)
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
CameraBounds = boxBounds == null ? CameraBounds : boxBounds.bounds;
|
|
|
|
|
|
Gizmos.DrawWireCube(CameraBounds.center, CameraBounds.size);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-04-28 15:26:51 +08:00
|
|
|
|
}
|