好多新内容

This commit is contained in:
2026-07-22 05:35:53 +08:00
parent b5d1cdcbc5
commit 15649d02f8
128 changed files with 5956 additions and 673 deletions
@@ -86,7 +86,14 @@ public class NoteSpawner : MonoBehaviour
// optional: constants for runtime clamping (kept for internal use)
private const float SpeedMultiplierMin = 0.5f;
private const float SpeedMultiplierMax = 2f;
private const float FlowSpeedGlobalMultiplier = 1.5f;
// 全局流速系数:与用户可调流速(speedMultiplier)相乘的独立系数,加快音符下落。
// 为什么用它而非 bpm 倍率:noteSpeed = 10.75 * sm * bpm / 240,若靠 ×bpm 提速,
// 长条音符的视觉长度由 ApplyVisualScale(sm) 决定(只随 sm 不随 bpm)、且分段数 segmentInterval=(60/bpm)/4
// 也会变,导致长条视觉与下落速度不匹配而错乱。故 bpm 方案不可行;sm 才是让 noteSpeed 与
// 长条视觉/粒子一致缩放的唯一安全杠杆。按用户指示设为 2。
// 判定不受影响:音符恒在 hitTime 抵达判定线,speed 仅改视觉下落快慢与出现时机,
// 判定链只依赖真实音符时间(hitTime ± range),与 speed 无共享变量。
private const float FlowSpeedGlobalMultiplier = 2.0f;
public float EffectiveSpeedMultiplier
{
@@ -125,6 +132,8 @@ public class NoteSpawner : MonoBehaviour
private void Awake()
{
// 去物理判定:清空上一场景/上一局缓存的判定线几何,重新捕获(判定线位置可能变)。
JudgeZoneGeometry.Reset();
EnsureDefaultNoteSpeedPreference();
// Load saved visual speed multiplier before any spawning logic uses it
float saved = PlayerPrefs.GetFloat(NoteSpeedPrefKey, NoteSpeedDefault);
@@ -576,9 +585,18 @@ public class NoteSpawner : MonoBehaviour
private void EnsureJudgmentLine()
{
if (judgmentLine != null) return;
GameObject go = GameObject.FindGameObjectWithTag("JudgmentLine");
if (go != null) judgmentLine = go.transform;
if (judgmentLine == null)
{
GameObject go = GameObject.FindGameObjectWithTag("JudgmentLine");
if (go != null) judgmentLine = go.transform;
}
// 去物理判定:捕获判定线 collider 的世界 Y 范围(只一次),供音符用几何阈值判进出判定区。
if (judgmentLine != null && !JudgeZoneGeometry.LineReady)
{
Collider2D lineCol = judgmentLine.GetComponent<Collider2D>();
if (lineCol == null) lineCol = judgmentLine.GetComponentInChildren<Collider2D>();
if (lineCol != null) JudgeZoneGeometry.CaptureLine(lineCol);
}
}
private float[] BuildLaneTravelTimes(float noteSpeed)