diff --git a/Cyan-Stars/Assets/Scripts/Gameplay/MusicGame/Note/Logic/HoldNote.cs b/Cyan-Stars/Assets/Scripts/Gameplay/MusicGame/Note/Logic/HoldNote.cs index 0ac18476..d3c70d55 100644 --- a/Cyan-Stars/Assets/Scripts/Gameplay/MusicGame/Note/Logic/HoldNote.cs +++ b/Cyan-Stars/Assets/Scripts/Gameplay/MusicGame/Note/Logic/HoldNote.cs @@ -1,12 +1,8 @@ -using CyanStars.Framework.Logging; - +using CyanStars.Framework; using UnityEngine; namespace CyanStars.Gameplay.MusicGame { - /// - /// Hold音符 - /// public class HoldNote : BaseNote { /// @@ -44,6 +40,8 @@ public class HoldNote : BaseNote /// private float value; + private readonly MusicGameSettingsModule + MusicGameSettingsModule = GameRoot.GetDataModule(); public override void Init(NoteData data, NoteLayer layer) @@ -51,7 +49,7 @@ public override void Init(NoteData data, NoteLayer layer) base.Init(data, layer); holdLength = (data.HoldEndTime - data.JudgeTime) / 1000f; - holdCheckInputEndDistance = -holdLength;//hold结束时间点与长度相同 + holdCheckInputEndDistance = -holdLength; //hold结束时间点与长度相同 } public override bool CanReceiveInput() @@ -59,12 +57,57 @@ public override bool CanReceiveInput() return Distance <= EvaluateHelper.CheckInputStartDistance && Distance >= holdCheckInputEndDistance; } - public override void OnUpdate(float curLogicTime,float curViewTime) + public override void OnUpdateInAutoMode(float curLogicTime, float curViewTime) { - float deltaTime = curLogicTime - CurLogicTime; + base.OnUpdateInAutoMode(curLogicTime, curViewTime); + + var holdViewObject = ViewObject as HoldViewObject; + + if (!headChecked && Distance <= 0) + { + headChecked = true; + + holdViewObject?.OpenFlicker(); + + ViewObject.CreateEffectObj(NoteData.NoteWidth); + NoteJudger.HoldHeadJudge(Data, 0); // Auto Mode 杂率为0 + + holdViewObject?.SetPressed(true); + } + + if (headChecked) + { + // 按下时根据已经经过的视图层时间比例计算Hold长度 + float length = Data.HoldViewEndTime / 1000f - curViewTime; + holdViewObject?.SetLength(length); + } + + if (Distance < holdCheckInputEndDistance) + { + ViewObject?.DestroyEffectObj(); + DestroySelf(false); + + NoteJudger.HoldTailJudge(Data, holdLength, 1); + } + } + + public override void OnUpdate(float curLogicTime, float curViewTime) + { + // 1. 判定头判 Miss + // 2. 累加这一帧的按住时长,并计算视图长度 + // 3. 判定尾判 + float deltaTime = curLogicTime - CurLogicTime; base.OnUpdate(curLogicTime, curViewTime); + // 头判 Miss + if (!headChecked && EvaluateHelper.IsMiss(Distance)) + { + headChecked = true; + NoteJudger.HoldHeadJudge(Data, Distance); + } + + // 累加时长 if (!isPressed) { //这里isPressed为false 就表示从上一次OnUpdate到这次OnUpdate之间没有Press类型的输入 @@ -75,90 +118,68 @@ public override void OnUpdate(float curLogicTime,float curViewTime) //重置Press标记 isPressed = false; - if (Distance <= 0 && Distance >= holdCheckInputEndDistance) + if (Distance <= Mathf.Abs(MusicGameSettingsModule.EvaluateRange.Great) && + Distance >= holdCheckInputEndDistance) { - //只在hold音符区域内有按住时,累计有效时长 + // 只在 判定时间-Great区间~结束时间 区间内才累计时长 + pressTimeLength += deltaTime; - - // 按下时根据已经经过的视图层时间比例计算Hold长度 + + // 按下时根据已经经过的视图层时间比例计算 Hold 长度 float length = Data.HoldViewEndTime / 1000f - curViewTime; - (ViewObject as HoldViewObject).SetLength(length); + (ViewObject as HoldViewObject)?.SetLength(length); } } - if (Distance < holdCheckInputEndDistance) + // Hold 已结束(当前时间>Hold尾判时间,且当前时间>Hold头判时间+头判Right区间) + // 判定尾判 + if (Distance < holdCheckInputEndDistance && + Distance < MusicGameSettingsModule.EvaluateRange.Right) { - //整条hold都跑完了 - if (!headChecked) + float allLength; + if (Data.HoldEndTime / 1000f > + Data.JudgeTime / 1000f + Mathf.Abs(MusicGameSettingsModule.EvaluateRange.Right)) { - //没进行过头判 被漏掉了 miss - NoteJudger.HoldMiss(Data); + // 一般情况:Hold 结束时间大于开始时间+Right区间 + // 要求按住的总时长s = Hold结束时间 - (Hold开始时间 + Right区间) + allLength = Data.HoldEndTime / 1000f - + (Data.JudgeTime / 1000f + Mathf.Abs(MusicGameSettingsModule.EvaluateRange.Right)); } else { - //进行过头判 计算按住比例 - //总长度默认为hold长度 - float allLength = holdLength; - if (headCheckTime > JudgeTime) - { - //头判晚命中的情况下 以头判命中时间为起点计算总长度 - allLength = Data.HoldEndTime / 1000f - headCheckTime; - } + // 极短的 Hold:Hold 结束时间小开始时间+Right区间 + // 此时只要头判非 Miss,或头判 Miss 但从头判前就按住了对应位置(无KeyDown但KeyPress),尾判都算 Exact + allLength = 0; + } - //修正因累加deltaTime可能导致的按住时长比总时长大的情况 + if (allLength != 0) + { + // 正常判定 pressTimeLength = Mathf.Clamp(pressTimeLength, pressTimeLength, allLength); - - //计算按住比例 value = pressTimeLength / allLength; - - NoteJudger.HoldTailJudge(Data,pressTimeLength,value); - - ViewObject.DestroyEffectObj(); + NoteJudger.HoldTailJudge(Data, pressTimeLength, value); + } + else + { + // 短 Hold 判定 + if (headCheckTime == 0 && pressTimeLength == 0) + { + NoteJudger.HoldTailJudge(Data, pressTimeLength, 0f); + } + else + { + NoteJudger.HoldTailJudge(Data, pressTimeLength, 1f); + } } - DestroySelf(); - } - - } - - public override void OnUpdateInAutoMode(float curLogicTime,float curViewTime) - { - base.OnUpdateInAutoMode(curLogicTime, curViewTime); - - var holdViewObject = ViewObject as HoldViewObject; - - if (!headChecked && Distance <= 0) - { - headChecked = true; - - holdViewObject.OpenFlicker(); - - ViewObject.CreateEffectObj(NoteData.NoteWidth); - - NoteJudger.HoldHeadJudge(Data, 0); // Auto Mode 杂率为0 - - holdViewObject.SetPressed(true); - } - - if (headChecked) - { - // 按下时根据已经经过的视图层时间比例计算Hold长度 - float length = Data.HoldViewEndTime / 1000f - curViewTime; - holdViewObject.SetLength(length); - } - if (Distance < holdCheckInputEndDistance) - { ViewObject?.DestroyEffectObj(); - DestroySelf(); - - NoteJudger.HoldTailJudge(Data,holdLength,1); + DestroySelf(false); } } public override void OnInput(InputType inputType) { base.OnInput(inputType); - var holdViewObject = ViewObject as HoldViewObject; switch (inputType) { @@ -168,47 +189,34 @@ public override void OnInput(InputType inputType) return; } - //头判处理 - EvaluateType et = NoteJudger.HoldHeadJudge(Data, Distance); - if (et == EvaluateType.Bad || et == EvaluateType.Miss) - { - //头判失败直接销毁 - DestroySelf(false); - } - else - { - //头判成功 - headChecked = true; - headCheckTime = CurLogicTime; - isPressed = true; - // 按键按下,开始截断 - holdViewObject.SetPressed(true); - - ViewObject.CreateEffectObj(NoteData.NoteWidth); - //头判处理 - holdViewObject.OpenFlicker(); - } + // 进行头判 + NoteJudger.HoldHeadJudge(Data, Distance); + headChecked = true; + headCheckTime = CurLogicTime; + isPressed = true; + // 按键按下,开始截断和特效 + holdViewObject?.SetPressed(true); + ViewObject.CreateEffectObj(NoteData.NoteWidth); + holdViewObject?.OpenFlicker(); break; case InputType.Press: + // 提前按住也计算时长,但不截断或播放特效 + isPressed = true; + if (!headChecked) { - return; + return; } - //头判命中后 有Press输入 才开始计算命中时长 - isPressed = true; - // 按键按下,开始截断 - holdViewObject.SetPressed(true); - + holdViewObject?.SetPressed(true); ViewObject.CreateEffectObj(NoteData.NoteWidth); break; case InputType.Up: // 按键抬起,取消截断 - holdViewObject.SetPressed(false); - + holdViewObject?.SetPressed(false); break; } }