NLDClient-yudde/ProjectNLD/Assets/Code/Scripts/GameWrapper/Camera/CameraData.cs

144 lines
5.1 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using System;
using UnityEngine;
using Sirenix.OdinInspector;
[ExecuteAlways]
public class CameraData : MonoBehaviour
{
public const float CameraStartY = 25;
public const float CameraStartSize = 12;
public float CameraStartFOV = 30;
public const float NearClipPlane = 0.03f;
public const float FarClipPlane = 150;
public readonly Vector3 CameraStartRotationO = new Vector3(37.5f, -10f, 0f);
public readonly Vector3 CameraStartRotationP = new Vector3(45, -10, 0);
//之前的缩放是6次滚轮从最小放到最大故每一次缩放的值为1/6f
public 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;
private Camera mainCamera;
public Camera MainCamera => mainCamera;
public Bounds CameraBounds { get; set; }
// 运行时配置
public bool FingerMoveEnable { get; set; } = true;
// 对外提供是否使用正交相机的接口
public bool UseOrthographicMode => CameraSettingsManager.CurrentSettings.UseOrthographicMode;
private void Awake()
{
mainCamera = GetComponent<Camera>();
CameraBounds = boxBounds != null ? boxBounds.bounds : CameraBounds;
// 根据设置初始化相机
InitializeCamera();
}
private void InitializeCamera()
{
bool useOrthographic = UseOrthographicMode;
if (useOrthographic)
{
mainCamera.orthographic = true;
mainCamera.orthographicSize = CameraStartSize;
}
else
{
mainCamera.orthographic = false;
mainCamera.fieldOfView = CameraStartFOV;
}
mainCamera.nearClipPlane = NearClipPlane;
mainCamera.farClipPlane = FarClipPlane;
}
private void OnDrawGizmos()
{
if (mainCamera != null)
{
Gizmos.color = Color.red;
var cameraTransform = transform;
var position = cameraTransform.position;
float size = IsOrthographic ? mainCamera.orthographicSize :
mainCamera.fieldOfView * (CameraMaxSize - CameraMinSize) / (CameraMaxFOV - CameraMinFOV);
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);
}
}
public bool IsOrthographic => mainCamera.orthographic;
public Vector3 CalculateHitHorizontalPosition(Vector3 startPosition, Vector3 dir, float y)
{
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);
}
}