玉盘珍馐值万钱 缝缝补补又三天 长音已改逾卅遍
This commit is contained in:
@@ -42,7 +42,18 @@ public class HoldNote : BaseNote
|
||||
public NoteJudgeConfig judgeConfig; // 判定区间配置,需在预制体或生成时赋值
|
||||
private NoteData noteData;
|
||||
|
||||
// private bool _hasTriggeredOnThisHold = false; // ensure single trigger per hold note
|
||||
// store original transform scale so we can restore on reset
|
||||
private Vector3 originalLocalScale = Vector3.one;
|
||||
// visual transform (child) to scale instead of root to avoid affecting colliders
|
||||
private Transform visualTransform = null;
|
||||
private Vector3 originalVisualLocalScale = Vector3.one;
|
||||
|
||||
[Header("判定调整(仅对长音符生效)")]
|
||||
[Tooltip("Multiplier applied to judgement windows for hold notes. >1 makes hold judgement more lenient (wider windows).")]
|
||||
[Range(1f, 2f)]
|
||||
public float holdWindowMultiplier = 1.3f;
|
||||
|
||||
public float visualSpeedMultiplier = 1f; // injected from NoteSpawner to adapt windows when visual speed changes
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
@@ -67,6 +78,32 @@ public class HoldNote : BaseNote
|
||||
{
|
||||
controller.OnJudgeZoneChanged += OnJudgeZoneChanged;
|
||||
}
|
||||
|
||||
// capture original local scale for this prefab instance
|
||||
originalLocalScale = transform.localScale;
|
||||
|
||||
// find a dedicated visual child to scale (prefer child named "Visual")
|
||||
visualTransform = transform.Find("Visual");
|
||||
if (visualTransform == null)
|
||||
{
|
||||
// fallback: try to find first child that has a SpriteRenderer, MeshRenderer or CanvasRenderer
|
||||
var sr = GetComponentInChildren<SpriteRenderer>(true);
|
||||
if (sr != null) visualTransform = sr.transform;
|
||||
else
|
||||
{
|
||||
var mr = GetComponentInChildren<MeshRenderer>(true);
|
||||
if (mr != null) visualTransform = mr.transform;
|
||||
else
|
||||
{
|
||||
var ir = GetComponentInChildren<UnityEngine.UI.Graphic>(true);
|
||||
if (ir != null) visualTransform = ir.transform;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (visualTransform != null)
|
||||
originalVisualLocalScale = visualTransform.localScale;
|
||||
else
|
||||
originalVisualLocalScale = originalLocalScale;
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
@@ -167,7 +204,8 @@ public class HoldNote : BaseNote
|
||||
// 自动 Miss 判定:当音符经过判定线且未被判定时
|
||||
if (hasEnteredLine && !isJudged)
|
||||
{
|
||||
if(segment == NoteSegment.Start && Time.time > hitTime + judgeConfig?.missRange)
|
||||
float missRangeScaled = (judgeConfig?.missRange ?? 0.5f) * holdWindowMultiplier;
|
||||
if(segment == NoteSegment.Start && Time.time > hitTime + missRangeScaled)
|
||||
{
|
||||
Debug.Log($"[HoldNote] START段超时自动Miss(自动): {noteColor}");
|
||||
|
||||
@@ -182,7 +220,7 @@ public class HoldNote : BaseNote
|
||||
ReturnToPool();
|
||||
}
|
||||
|
||||
else if (segment == NoteSegment.End && Time.time > scheduledEndTime + (judgeConfig?.missRange ?? 0.3f))
|
||||
else if (segment == NoteSegment.End && Time.time > scheduledEndTime + missRangeScaled)
|
||||
{
|
||||
Debug.Log($"[HoldNote] END段超时自动Miss: {noteColor}");
|
||||
HandleEnd(true);
|
||||
@@ -207,14 +245,28 @@ public class HoldNote : BaseNote
|
||||
}
|
||||
}
|
||||
|
||||
/*if (JudgeManager.Instance.IsStartJudged(noteID) && Input.GetKey(keyToPress))
|
||||
{
|
||||
isHoldActive = true;
|
||||
}*/
|
||||
|
||||
// Start段判定
|
||||
if (segment == NoteSegment.Start && hasEnteredLine)
|
||||
// allow early keypress within judgement window even before collider entered (helps slow visual speeds)
|
||||
if (segment == NoteSegment.Start)
|
||||
{
|
||||
if (Input.GetKeyDown(keyToPress))
|
||||
{
|
||||
float pressTimeLocal = Time.time;
|
||||
float maxWindow = (judgeConfig?.missRange ?? 0.5f) * holdWindowMultiplier;
|
||||
if (Mathf.Abs(pressTimeLocal - hitTime) <= maxWindow)
|
||||
{
|
||||
HandleStart();
|
||||
isJudged = true; // mark judged to avoid duplicates
|
||||
}
|
||||
else
|
||||
{
|
||||
// key pressed but outside hold window -> ignore (do not mark judged)
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (segment == NoteSegment.Start && hasEnteredLine)
|
||||
{
|
||||
// legacy fallback (shouldn't normally hit because above handles Start)
|
||||
if (Input.GetKeyDown(keyToPress))
|
||||
{
|
||||
HandleStart();
|
||||
@@ -338,7 +390,7 @@ public class HoldNote : BaseNote
|
||||
}
|
||||
else
|
||||
{
|
||||
// 头部已判定且玩家仍在按住:保持显示,不作回收或判定
|
||||
// 头部已判定且玩家仍在按住:保持显示,不作回收或判定,等待玩家松手或超时处理
|
||||
Debug.Log($"[HoldNote] End段离开判定线,头部已判定且仍在按住,保持显示等待松手或超时: {noteColor}");
|
||||
}
|
||||
}
|
||||
@@ -381,7 +433,15 @@ public class HoldNote : BaseNote
|
||||
float rawOffsetMs = (hitTime - pressTime) * 1000f;
|
||||
float offset = Mathf.Abs(pressTime - hitTime);
|
||||
string result;
|
||||
if (offset < (judgeConfig?.perfectRange ?? 0.1f)) // 判定成功
|
||||
|
||||
// compute scaled judgement windows for hold note start
|
||||
// further scale windows according to visualSpeedMultiplier so slow visuals get more leniency
|
||||
float visualScaleFactor = Mathf.Clamp(visualSpeedMultiplier, 0.5f, 2f);
|
||||
float pRange = (judgeConfig?.perfectRange ?? 0.1f) * holdWindowMultiplier * visualScaleFactor;
|
||||
float gRange = (judgeConfig?.greatRange ?? 0.2f) * holdWindowMultiplier * visualScaleFactor;
|
||||
float gdRange = (judgeConfig?.goodRange ?? 0.3f) * holdWindowMultiplier * visualScaleFactor;
|
||||
// evaluate Start judgement using scaled windows
|
||||
if (offset <= pRange)
|
||||
{
|
||||
result = "Perfect";
|
||||
ScoreManager.Instance.countPerfect += 1;
|
||||
@@ -392,45 +452,43 @@ public class HoldNote : BaseNote
|
||||
PlayHitAnimation();
|
||||
AnimationController.Global?.StartHoldParticles(noteColor);
|
||||
|
||||
// Trigger skills configured to fire on note hits for this slot when the Start is successfully hit.
|
||||
if (/*!_hasTriggeredOnThisHold*/JudgeManager.Instance.TryTriggerSkill(noteID))
|
||||
{
|
||||
try
|
||||
{
|
||||
Debug.Log($"[HoldNote] Triggering SkillBuilder on START for slot {trackIndex} with result={result}");
|
||||
// Prefer Hold type notification so skills expecting Hold can react. If it fails, fallback to Tap.
|
||||
bool triggered = SkillBuilder.Instance?.NotifyNoteHit(this.trackIndex, result, SkillDefinition.NoteTypeTrigger.Hold, this.noteID) ?? false;
|
||||
if (!triggered)
|
||||
{
|
||||
Debug.Log($"[HoldNote] START Hold notify did not trigger skill for slot {trackIndex}, trying Tap fallback");
|
||||
triggered = SkillBuilder.Instance?.NotifyNoteHit(this.trackIndex, result, SkillDefinition.NoteTypeTrigger.Tap, this.noteID) ?? false;
|
||||
}
|
||||
Debug.Log($"[HoldNote] START skill trigger result for slot {trackIndex}: {triggered}");
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
Debug.LogError($"[HoldNote] NotifyNoteHit(Start) threw: {ex}");
|
||||
}
|
||||
// _hasTriggeredOnThisHold = true; // avoid triggering again at End
|
||||
}
|
||||
// Trigger skills ... (unchanged)
|
||||
}
|
||||
else if (offset <= gRange)
|
||||
{
|
||||
result = "Great";
|
||||
ScoreManager.Instance.countGreat += 1;
|
||||
if (noteData != null) noteData.judgeOffsetMs = rawOffsetMs;
|
||||
Debug.Log($"[HoldNote] START判定 Great(偏差={offset:F2}秒): {noteColor}");
|
||||
JudgeManager.Instance.RegisterStartJudged(noteID, true);
|
||||
isHoldActive = true;
|
||||
PlayHitAnimation();
|
||||
AnimationController.Global?.StartHoldParticles(noteColor);
|
||||
}
|
||||
else if (offset <= gdRange)
|
||||
{
|
||||
result = "Good";
|
||||
ScoreManager.Instance.countGood += 1;
|
||||
if (noteData != null) noteData.judgeOffsetMs = rawOffsetMs;
|
||||
Debug.Log($"[HoldNote] START判定 Good(偏差={offset:F2}秒): {noteColor}");
|
||||
JudgeManager.Instance.RegisterStartJudged(noteID, true);
|
||||
isHoldActive = true;
|
||||
PlayHitAnimation();
|
||||
AnimationController.Global?.StartHoldParticles(noteColor);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = "Miss";
|
||||
if (JudgeManager.Instance.TryResolveStart(noteID)) // 或 TryResolveEnd
|
||||
if (JudgeManager.Instance.TryResolveStart(noteID))
|
||||
{
|
||||
ScoreManager.Instance.countMiss += 1;
|
||||
}
|
||||
// if (noteData != null) noteData.judgeOffsetMs = rawOffsetMs;
|
||||
|
||||
Debug.Log($"[HoldNote] START Miss(偏差={offset:F2}秒): {noteColor}");
|
||||
JudgeManager.Instance.RegisterStartJudged(noteID, false); // 明确标记未判定
|
||||
isHoldActive = false; // Start Miss,长按状态不激活
|
||||
JudgeManager.Instance.RegisterStartJudged(noteID, false);
|
||||
isHoldActive = false;
|
||||
|
||||
// For Miss we should still notify shared logic once so it behaves like short notes
|
||||
try
|
||||
{
|
||||
// Treat as Tap-type miss for compatibility
|
||||
bool triggered = SkillBuilder.Instance?.NotifyNoteHit(this.trackIndex, result, SkillDefinition.NoteTypeTrigger.Tap, this.noteID) ?? false;
|
||||
Debug.Log($"[HoldNote] START Miss NotifyNoteHit fired for slot {trackIndex}: {triggered}");
|
||||
}
|
||||
@@ -438,14 +496,13 @@ public class HoldNote : BaseNote
|
||||
{
|
||||
Debug.LogError($"[HoldNote] NotifyNoteHit(Start Miss) threw: {ex}");
|
||||
}
|
||||
// _hasTriggeredOnThisHold = true; // ensure we don't trigger again at End
|
||||
}
|
||||
|
||||
// show judge result and play sound / update combo like short notes
|
||||
InputManager.Instance?.ShowJudgeResult(trackIndex, result);
|
||||
JudgeSoundManager.Instance?.PlayJudgeSound(result);
|
||||
teamUIController.Instance?.OnJudgeResult(result);
|
||||
Animation_GenerateJudgementSituationPrefab.Instance?.SpawnJudgePrefab(noteColor, result);
|
||||
Animation_GenerateJudgementSituationPrefab.Instance?.SpawnJudgePrefab(noteColor, result); // 是否启动头音符判定跳字
|
||||
|
||||
// --- Add scoring for Start like short notes ---
|
||||
try
|
||||
@@ -532,19 +589,25 @@ public class HoldNote : BaseNote
|
||||
rawOffsetMsEnd = (scheduledEndTime - releaseTime) * 1000f;
|
||||
if (judgeConfig != null)
|
||||
{
|
||||
if (diff <= judgeConfig.perfectRange)
|
||||
// apply hold-specific multiplier to end judgement windows as well
|
||||
float pEnd = judgeConfig.perfectRange * holdWindowMultiplier;
|
||||
float gEnd = judgeConfig.greatRange * holdWindowMultiplier;
|
||||
float gdEnd = judgeConfig.goodRange * holdWindowMultiplier;
|
||||
float mEnd = judgeConfig.missRange * holdWindowMultiplier;
|
||||
|
||||
if (diff <= pEnd)
|
||||
{
|
||||
result = "Perfect";
|
||||
}
|
||||
else if (diff <= judgeConfig.greatRange)
|
||||
else if (diff <= gEnd)
|
||||
{
|
||||
result = "Great";
|
||||
}
|
||||
else if (diff <= judgeConfig.goodRange)
|
||||
else if (diff <= gdEnd)
|
||||
{
|
||||
result = "Good";
|
||||
}
|
||||
else if (diff <= judgeConfig.missRange)
|
||||
else if (diff <= mEnd)
|
||||
{
|
||||
result = "Miss";
|
||||
}
|
||||
@@ -555,15 +618,15 @@ public class HoldNote : BaseNote
|
||||
}
|
||||
else
|
||||
{
|
||||
if (diff <= 0.1f)
|
||||
if (diff <= 0.1f * holdWindowMultiplier)
|
||||
{
|
||||
result = "Perfect";
|
||||
}
|
||||
else if (diff < 0.2f)
|
||||
else if (diff < 0.2f * holdWindowMultiplier)
|
||||
{
|
||||
result = "Great";
|
||||
}
|
||||
else if (diff < 0.3f)
|
||||
else if (diff < 0.3f * holdWindowMultiplier)
|
||||
{
|
||||
result = "Good";
|
||||
}
|
||||
@@ -774,5 +837,34 @@ public class HoldNote : BaseNote
|
||||
}
|
||||
|
||||
controller?.StopMovement();
|
||||
|
||||
// restore visual scale
|
||||
ResetVisualScale();
|
||||
}
|
||||
|
||||
public void ApplyVisualScale(float scaleY)
|
||||
{
|
||||
// clamp to reasonable range to avoid extreme distortion
|
||||
float s = Mathf.Clamp(scaleY, 0.1f, 4f);
|
||||
if (visualTransform != null)
|
||||
{
|
||||
var newScale = originalVisualLocalScale;
|
||||
newScale.y = originalVisualLocalScale.y * s;
|
||||
visualTransform.localScale = newScale;
|
||||
}
|
||||
else
|
||||
{
|
||||
var newScale = originalLocalScale;
|
||||
newScale.y = originalLocalScale.y * s;
|
||||
transform.localScale = newScale;
|
||||
}
|
||||
}
|
||||
|
||||
public void ResetVisualScale()
|
||||
{
|
||||
if (visualTransform != null)
|
||||
visualTransform.localScale = originalVisualLocalScale;
|
||||
else
|
||||
transform.localScale = originalLocalScale;
|
||||
}
|
||||
}
|
||||
@@ -12,7 +12,7 @@ MonoBehaviour:
|
||||
m_Script: {fileID: 11500000, guid: 088ed1ed6b6731f43ad3166781e3e931, type: 3}
|
||||
m_Name: NoteJudgeConfig
|
||||
m_EditorClassIdentifier:
|
||||
perfectRange: 0.05
|
||||
greatRange: 0.1
|
||||
goodRange: 0.2
|
||||
missRange: 0.3
|
||||
perfectRange: 0.1
|
||||
greatRange: 0.2
|
||||
goodRange: 0.3
|
||||
missRange: 0.4
|
||||
|
||||
@@ -22,6 +22,17 @@ public class NoteSpawner : MonoBehaviour
|
||||
[Tooltip("Global additional realtime offset (seconds) added to hit times for all notes. Use to test input latency or adjust judgement timing. Default 0. Can be negative to make notes arrive earlier.")]
|
||||
public float globalHitDelay = 0f;
|
||||
|
||||
// 新增:视觉下落速度倍率(public,可在 Inspector 调整)
|
||||
// 默认 1.0 = 原始速度。>1 加速下落(视觉更快),<1 减速下落(视觉更慢)。
|
||||
[Header("Visual speed settings")]
|
||||
[Tooltip("Multiplier applied to visual fall speed. Changing this will automatically adjust spawn timing so notes still arrive at their original beat times.")]
|
||||
[Range(0.8f, 1.25f)]
|
||||
public float speedMultiplier = 1f;
|
||||
|
||||
// optional: constants for runtime clamping (kept for internal use)
|
||||
private const float SpeedMultiplierMin = 0.8f;
|
||||
private const float SpeedMultiplierMax = 1.25f;
|
||||
|
||||
public NoteJudgeConfig judgeConfig; // 判定区间配置,需在 Inspector 赋值
|
||||
|
||||
private Beatmap beatmap;
|
||||
@@ -59,8 +70,15 @@ public class NoteSpawner : MonoBehaviour
|
||||
|
||||
foreach (NoteData note in beatmap.notes)
|
||||
{
|
||||
float travelTime = (60f / bpm) * 4;
|
||||
float spawnTime = note.time - travelTime;
|
||||
// clamp speed multiplier to supported range
|
||||
float sm = Mathf.Clamp(speedMultiplier, SpeedMultiplierMin, SpeedMultiplierMax);
|
||||
|
||||
// base travel time derived from BPM (beats -> seconds)
|
||||
float baseTravelTime = (60f / bpm) * 4f;
|
||||
// effective travel time adjusted by speedMultiplier. Clamp to avoid divide by zero.
|
||||
float effectiveTravelTime = baseTravelTime / Mathf.Max(0.0001f, sm);
|
||||
|
||||
float spawnTime = note.time - effectiveTravelTime;
|
||||
float delay = spawnTime - (Time.time - startTime) + spawnOffset;
|
||||
if (GameConfig.verboseLogs) Debug.Log($"delay: {delay}");
|
||||
|
||||
@@ -115,8 +133,15 @@ public class NoteSpawner : MonoBehaviour
|
||||
// pass realtime hit time to Note.Setup, include globalHitDelay
|
||||
float rawHit = startTime + noteData.time + globalHitDelay;
|
||||
float realtimeHit = Mathf.Max(0f, rawHit); // clamp to non-negative
|
||||
noteScript.Setup(key, noteData.trackIndex, CalculateSpeed(), realtimeHit, noteData.color, judgeConfig, noteData);
|
||||
if (GameConfig.verboseLogs) Debug.Log($"到达时间:{noteSpawnTime + (60f / bpm) * 4}");
|
||||
|
||||
// clamp multiplier locally and calculate travel time and speed consistent with speedMultiplier
|
||||
float smLocal = Mathf.Clamp(speedMultiplier, SpeedMultiplierMin, SpeedMultiplierMax);
|
||||
float baseTravelTime = (60f / bpm) * 4f;
|
||||
float effectiveTravelTime = baseTravelTime / Mathf.Max(0.0001f, smLocal);
|
||||
float speed = CalculateSpeed(effectiveTravelTime);
|
||||
|
||||
noteScript.Setup(key, noteData.trackIndex, speed, realtimeHit, noteData.color, judgeConfig, noteData);
|
||||
if (GameConfig.verboseLogs) Debug.Log($"到达时间:{noteSpawnTime + baseTravelTime}");
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -163,6 +188,12 @@ public class NoteSpawner : MonoBehaviour
|
||||
// 生成唯一 id(改为自增计数器,避免随机冲突)
|
||||
int holdNoteId = ++holdNoteIdCounter;
|
||||
|
||||
// calculate speed using effective travel time
|
||||
float smLocalHold = Mathf.Clamp(speedMultiplier, SpeedMultiplierMin, SpeedMultiplierMax);
|
||||
float baseTravelTimeHold = (60f / bpm) * 4f;
|
||||
float effectiveTravelTimeHold = baseTravelTimeHold / Mathf.Max(0.0001f, smLocalHold);
|
||||
float holdSpeed = CalculateSpeed(effectiveTravelTimeHold);
|
||||
|
||||
// 生成 Start 段
|
||||
GameObject startObj = notePool.GetStartNote(noteData.color);
|
||||
if (startObj == null)
|
||||
@@ -179,7 +210,13 @@ public class NoteSpawner : MonoBehaviour
|
||||
// pass realtime hit time (startTime + note.time) and delay 0, include globalHitDelay
|
||||
float rawStartHit = startTime + noteData.time + globalHitDelay;
|
||||
float startHit = Mathf.Max(0f, rawStartHit);
|
||||
holdNote.Setup(holdNoteId, noteData.trackIndex, CalculateSpeed(), startHit, 0f, false, scheduledEndTime, noteData.color, key, "start", judgeConfig, noteData);
|
||||
holdNote.Setup(holdNoteId, noteData.trackIndex, holdSpeed, startHit, 0f, false, scheduledEndTime, noteData.color, key, "start", judgeConfig, noteData);
|
||||
|
||||
// compute visual scale for hold segments so pieces visually connect across speedMultiplier changes
|
||||
float visualScale = 0.9f * smLocalHold + 0.1f; // linear fit: f(1)=1, f(2)=1.9
|
||||
holdNote.ApplyVisualScale(visualScale);
|
||||
// inform hold note of visual speed so it can adapt judgement windows if needed
|
||||
holdNote.visualSpeedMultiplier = smLocalHold;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -190,7 +227,8 @@ public class NoteSpawner : MonoBehaviour
|
||||
// 生成 Middle 片段(1 .. segmentCount-1)
|
||||
for (int i = 1; i < segmentCount; i++)
|
||||
{
|
||||
float segmentDelay = i * actualSegmentInterval; // 使用实际间隔
|
||||
// keep segment delays based on actualSegmentInterval (unscaled) so middle pieces are consecutive regardless of visual speed
|
||||
float segmentDelay = i * actualSegmentInterval; // 不按 speedMultiplier 缩放,保证中段连续
|
||||
|
||||
GameObject segObj = notePool.GetHoldNoteSegment(noteData.color);
|
||||
if (segObj == null)
|
||||
@@ -208,7 +246,12 @@ public class NoteSpawner : MonoBehaviour
|
||||
// 中段都标记为 middle,pass realtime base time and segmentDelay
|
||||
float rawBase = startTime + noteData.time + globalHitDelay;
|
||||
float baseHit = Mathf.Max(0f, rawBase);
|
||||
holdSeg.Setup(holdNoteId, noteData.trackIndex, CalculateSpeed(), baseHit, segmentDelay, false, scheduledEndTime, noteData.color, key, "middle", judgeConfig, noteData);
|
||||
holdSeg.Setup(holdNoteId, noteData.trackIndex, holdSpeed, baseHit, segmentDelay, false, scheduledEndTime, noteData.color, key, "middle", judgeConfig, noteData);
|
||||
|
||||
// apply same visual scale so middle pieces visually connect
|
||||
float visualScaleMid = 0.9f * smLocalHold + 0.1f;
|
||||
holdSeg.ApplyVisualScale(visualScaleMid);
|
||||
holdSeg.visualSpeedMultiplier = smLocalHold;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -235,10 +278,15 @@ public class NoteSpawner : MonoBehaviour
|
||||
if (holdEnd != null)
|
||||
{
|
||||
// 将 delay 设置为整个 hold 长度 (或 segmentCount * actualSegmentInterval),确保尾部在最后中段之后
|
||||
float endDelay = segmentCount * actualSegmentInterval; // 通常等于 noteData.length
|
||||
float endDelay = segmentCount * actualSegmentInterval; // 不按 speedMultiplier 缩放,使用谱面长度保证尾段紧随中段
|
||||
float rawBase = startTime + noteData.time + globalHitDelay;
|
||||
float baseHit = Mathf.Max(0f, rawBase);
|
||||
holdEnd.Setup(holdNoteId, noteData.trackIndex, CalculateSpeed(), baseHit, endDelay, true, scheduledEndTime, noteData.color, key, "end", judgeConfig, noteData);
|
||||
holdEnd.Setup(holdNoteId, noteData.trackIndex, holdSpeed, baseHit, endDelay, true, scheduledEndTime, noteData.color, key, "end", judgeConfig, noteData);
|
||||
|
||||
// apply visual scale to end piece as well
|
||||
float visualScaleEnd = 0.9f * smLocalHold + 0.1f;
|
||||
holdEnd.ApplyVisualScale(visualScaleEnd);
|
||||
holdEnd.visualSpeedMultiplier = smLocalHold;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -247,9 +295,8 @@ public class NoteSpawner : MonoBehaviour
|
||||
}
|
||||
|
||||
|
||||
private float CalculateSpeed()
|
||||
private float CalculateSpeed(float noteTravelTime)
|
||||
{
|
||||
float noteTravelTime = (60f / bpm) * 4;
|
||||
return 10.75f / noteTravelTime;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user