92 lines
3.7 KiB
C#
92 lines
3.7 KiB
C#
using UnityEngine;
|
||
|
||
/// <summary>
|
||
/// 根据屏幕宽高比,对 gameplay 相机做"适当微调":叠加一点 X 旋转(俯角)与 Z 距离增量。
|
||
/// 目的:不同分辨率下让轨道透视观感更协调(如超宽屏略微拉远/调俯角),与 contain 式 FOV 适配互补。
|
||
///
|
||
/// 安全性(核心):**绝不直接写相机 transform**。所有微调通过 effectEventController.SetResolutionCameraAdjust
|
||
/// 施加到"漂移 pivot"(顶层基准节点),并由该方法同步漂移基准 z——因此与相机漂移、SmoothShake 抖动、
|
||
/// 技能偏移、冲刺特效等所有"写相机位姿"的业务逻辑完全不冲突(它们叠加在 pivot 之下或相机自身)。
|
||
///
|
||
/// 用一个 bool(enableTuning)开关。关闭时把增量清零(恢复设计基准),行为与未加此脚本一致。
|
||
/// 增量相对"设计基准"计算,不累积;16:9 时增量为 0(与原设计逐像素一致)。
|
||
/// </summary>
|
||
[DisallowMultipleComponent]
|
||
public sealed class CameraResolutionTuner : MonoBehaviour
|
||
{
|
||
[Tooltip("是否启用按分辨率微调相机(X旋转/Z)。关闭则恢复设计基准。")]
|
||
public bool enableTuning = true;
|
||
|
||
[Tooltip("设计基准宽高比。16:9 = 1.7778。此比例下增量为 0。")]
|
||
public float designAspect = 16f / 9f;
|
||
|
||
[Header("宽屏(aspect > 设计)微调")]
|
||
[Tooltip("每偏离设计宽高比 1.0,额外叠加的 X 旋转角度(正=更俯视)。建议很小。")]
|
||
public float widePerAspectRotX = 3f;
|
||
[Tooltip("每偏离设计宽高比 1.0,额外叠加的 Z 距离(负=相机后退拉远)。")]
|
||
public float widePerAspectZ = -1.0f;
|
||
[Tooltip("宽屏微调的绝对上限,避免极端超宽屏过度。")]
|
||
public float wideMaxRotX = 6f;
|
||
public float wideMaxZ = -2.0f;
|
||
|
||
[Header("窄屏(aspect < 设计)微调")]
|
||
[Tooltip("每偏离设计宽高比 1.0,额外叠加的 X 旋转角度。")]
|
||
public float narrowPerAspectRotX = 0f;
|
||
[Tooltip("每偏离设计宽高比 1.0,额外叠加的 Z 距离。")]
|
||
public float narrowPerAspectZ = 0f;
|
||
public float narrowMaxRotX = 4f;
|
||
public float narrowMaxZ = 2.0f;
|
||
|
||
private float _lastAspect = -1f;
|
||
private bool _lastEnabled;
|
||
|
||
private void OnEnable()
|
||
{
|
||
_lastAspect = -1f;
|
||
Apply();
|
||
}
|
||
|
||
private void Update()
|
||
{
|
||
float aspect = (float)Screen.width / Mathf.Max(1, Screen.height);
|
||
if (Mathf.Abs(aspect - _lastAspect) > 0.0001f || enableTuning != _lastEnabled)
|
||
{
|
||
Apply();
|
||
}
|
||
}
|
||
|
||
private void Apply()
|
||
{
|
||
var eff = effectEventController.Instance;
|
||
if (eff == null) return;
|
||
|
||
float aspect = (float)Screen.width / Mathf.Max(1, Screen.height);
|
||
_lastAspect = aspect;
|
||
_lastEnabled = enableTuning;
|
||
|
||
if (!enableTuning)
|
||
{
|
||
eff.SetResolutionCameraAdjust(0f, 0f); // 恢复设计基准
|
||
return;
|
||
}
|
||
|
||
float rotX = 0f;
|
||
float z = 0f;
|
||
if (aspect > designAspect)
|
||
{
|
||
float dev = aspect - designAspect; // 宽屏偏离量
|
||
rotX = Mathf.Clamp(widePerAspectRotX * dev, Mathf.Min(0f, wideMaxRotX), Mathf.Max(0f, wideMaxRotX));
|
||
z = Mathf.Clamp(widePerAspectZ * dev, Mathf.Min(0f, wideMaxZ), Mathf.Max(0f, wideMaxZ));
|
||
}
|
||
else if (aspect < designAspect)
|
||
{
|
||
float dev = designAspect - aspect; // 窄屏偏离量
|
||
rotX = Mathf.Clamp(narrowPerAspectRotX * dev, Mathf.Min(0f, narrowMaxRotX), Mathf.Max(0f, narrowMaxRotX));
|
||
z = Mathf.Clamp(narrowPerAspectZ * dev, Mathf.Min(0f, narrowMaxZ), Mathf.Max(0f, narrowMaxZ));
|
||
}
|
||
// 16:9:rotX=z=0,无微调。
|
||
|
||
eff.SetResolutionCameraAdjust(rotX, z);
|
||
}
|
||
}
|