121 lines
4.4 KiB
C#
121 lines
4.4 KiB
C#
using UnityEngine;
|
|
|
|
/// <summary>
|
|
/// 按屏幕宽高比动态拉长轨道视觉物体(track1-5)的 Y 缩放,让宽屏下轨道更饱满。
|
|
///
|
|
/// 原理:宽屏时水平视野大、轨道相对缩在中间显细。降相机高度+抬头能让轨道透视放大,
|
|
/// 但仍不够饱满。再叠加"拉长轨道 Y 缩放"填满纵向视野,视觉更满。
|
|
///
|
|
/// 关键:轨道只是背景视觉,判定是几何驱动(音符世界 Y vs 判定线世界 Y)。
|
|
/// 缩放轨道 localScale 不影响音符生成/下落/判定——它们全用世界坐标,与轨道视觉无关。
|
|
///
|
|
/// 用法:挂到场景任意物体(会自动找 track1-5 或指定 trackParent)。运行时自动扫描并缩放。
|
|
/// </summary>
|
|
[DisallowMultipleComponent]
|
|
public sealed class TrackScaler : MonoBehaviour
|
|
{
|
|
[Tooltip("是否启用轨道缩放。关闭则恢复基准值 2.5。")]
|
|
public bool enableScaling = true;
|
|
|
|
[Tooltip("设计基准宽高比。16:9 = 1.7778。此比例下缩放为基准值。")]
|
|
public float designAspect = 16f / 9f;
|
|
|
|
[Tooltip("轨道 Y 缩放的基准值(场景序列化的初始值)。从这个值开始按宽高比放大。")]
|
|
public float baseScaleY = 2.5f;
|
|
|
|
[Header("宽屏(aspect > 设计)缩放")]
|
|
[Tooltip("每偏离设计宽高比 1.0,额外叠加的 Y 缩放倍数。宽屏拉长轨道让视觉更满。")]
|
|
public float widePerAspectScaleY = 0.8f;
|
|
[Tooltip("Y 缩放的绝对上限。避免极端超宽屏拉得过长。")]
|
|
public float maxScaleY = 4.5f;
|
|
|
|
[Tooltip("(可选)轨道的父节点。留空则自动全场景查找 track1-5。")]
|
|
public Transform trackParent;
|
|
|
|
private Transform[] _tracks;
|
|
private float _lastAspect = -1f;
|
|
private bool _lastEnabled;
|
|
|
|
private void OnEnable()
|
|
{
|
|
FindTracks();
|
|
_lastAspect = -1f;
|
|
Apply();
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
float aspect = (float)Screen.width / Mathf.Max(1, Screen.height);
|
|
if (Mathf.Abs(aspect - _lastAspect) > 0.0001f || enableScaling != _lastEnabled)
|
|
{
|
|
Apply();
|
|
}
|
|
}
|
|
|
|
private void FindTracks()
|
|
{
|
|
if (trackParent != null)
|
|
{
|
|
// 从指定父节点下找
|
|
_tracks = new Transform[5];
|
|
for (int i = 0; i < trackParent.childCount; i++)
|
|
{
|
|
Transform child = trackParent.GetChild(i);
|
|
if (child.name == "track1") _tracks[0] = child;
|
|
else if (child.name == "track2") _tracks[1] = child;
|
|
else if (child.name == "track3") _tracks[2] = child;
|
|
else if (child.name == "track4") _tracks[3] = child;
|
|
else if (child.name == "track5") _tracks[4] = child;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// 全场景查找(慢,但兜底)
|
|
_tracks = new Transform[5];
|
|
GameObject go1 = GameObject.Find("track1");
|
|
GameObject go2 = GameObject.Find("track2");
|
|
GameObject go3 = GameObject.Find("track3");
|
|
GameObject go4 = GameObject.Find("track4");
|
|
GameObject go5 = GameObject.Find("track5");
|
|
if (go1 != null) _tracks[0] = go1.transform;
|
|
if (go2 != null) _tracks[1] = go2.transform;
|
|
if (go3 != null) _tracks[2] = go3.transform;
|
|
if (go4 != null) _tracks[3] = go4.transform;
|
|
if (go5 != null) _tracks[4] = go5.transform;
|
|
}
|
|
}
|
|
|
|
private void Apply()
|
|
{
|
|
if (_tracks == null || _tracks.Length == 0)
|
|
{
|
|
FindTracks(); // 重试
|
|
if (_tracks == null || _tracks.Length == 0) return;
|
|
}
|
|
|
|
float aspect = (float)Screen.width / Mathf.Max(1, Screen.height);
|
|
_lastAspect = aspect;
|
|
_lastEnabled = enableScaling;
|
|
|
|
float targetScaleY = baseScaleY;
|
|
|
|
if (enableScaling && aspect > designAspect)
|
|
{
|
|
// 宽屏:额外拉长 Y
|
|
float dev = aspect - designAspect;
|
|
float extra = widePerAspectScaleY * dev;
|
|
targetScaleY = Mathf.Min(baseScaleY + extra, maxScaleY);
|
|
}
|
|
// aspect <= designAspect 或关闭:保持基准值
|
|
|
|
// 应用到所有轨道
|
|
for (int i = 0; i < _tracks.Length; i++)
|
|
{
|
|
if (_tracks[i] == null) continue;
|
|
Vector3 scale = _tracks[i].localScale;
|
|
scale.y = targetScaleY;
|
|
_tracks[i].localScale = scale;
|
|
}
|
|
}
|
|
}
|