Files
ichni_Official/Assets/Scripts/Game/GameElements/Notes/NoteObjects/Hold.cs

303 lines
9.8 KiB
C#
Raw Normal View History

2025-06-03 02:42:28 -04:00
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Dreamteck.Splines;
using Ichni.RhythmGame.Beatmap;
2025-07-21 05:42:20 -04:00
using UniRx;
2025-06-03 02:42:28 -04:00
using Unity.VisualScripting;
using UnityEngine;
namespace Ichni.RhythmGame
{
public partial class Hold : NoteBase
{
public float holdEndTime;
public float holdingTime;
public bool isHolding;
2025-07-21 05:42:20 -04:00
public float holdingBufferTime;
public float bufferTimer;
public NoteJudgeType preJudgeType;
public NoteJudgeType postJudgeType;
2025-06-03 02:42:28 -04:00
public static Hold GenerateElement(string elementName, Guid id, List<string> tags, bool isFirstGenerated,
GameElement parentElement, float exactJudgeTime, float holdEndTime)
{
Hold hold = Instantiate(GameManager.instance.basePrefabs.holdNote, parentElement.transform).GetComponent<Hold>();
hold.Initialize(elementName, id, tags, isFirstGenerated, parentElement);
hold.exactJudgeTime = exactJudgeTime;
hold.holdEndTime = holdEndTime;
hold.holdingTime = 0;
2025-07-21 05:42:20 -04:00
hold.holdingBufferTime = 0.1f;
hold.judgeIntervals = new NoteJudgeIntervals(
new TimeInterval(-0.15f, -0.15f), new TimeInterval(-0.15f, -0.125f),
new TimeInterval(-0.125f, -0.1f), new TimeInterval(-0.1f, 0.1f),
new TimeInterval(0.1f, 0.125f), new TimeInterval(0.125f, 0.15f), 0.15f);
hold.preJudgeType = NoteJudgeType.NotJudged;
hold.postJudgeType = NoteJudgeType.NotJudged;
2025-06-03 02:42:28 -04:00
if (parentElement.TryGetComponent(out Track track))
{
if (track.trackTimeSubmodule != null)
{
hold.track = track;
hold.trackPositioner = hold.AddComponent<SplinePositioner>();
hold.trackPositioner.spline = track.trackPathSubmodule.path;
hold.trackPositioner.updateMethod = SplineUser.UpdateMethod.LateUpdate;
hold.isOnTrack = true;
hold.UpdateNoteInTrack();
}
else
{
throw new Exception("如果Note要生成在Track上Track必须有TrackTimeSubmodule组件。");
}
}
else
{
hold.track = null;
hold.isOnTrack = false;
}
return hold;
}
2025-07-21 05:42:20 -04:00
public override void ExecuteStartJudge()
{
float triggerTime = GameManager.instance.songTime;
float timeDifference = triggerTime - exactJudgeTime;
NoteJudgeType startJudgeType = GetStartJudgeType(timeDifference);
preJudgeType = startJudgeType;
isFirstJudged = true;
isHolding = true;
Debug.Log($"Hold Note Start Judge: {startJudgeType} at {triggerTime}");
}
public void ExecuteProcessJudge()
{
isHolding = true;
}
public void ExecuteFinalJudge()
{
float triggerTime = GameManager.instance.songTime;
float timeDifference = holdEndTime - triggerTime;
if (timeDifference <= 0.1f)
{
postJudgeType = NoteJudgeType.Perfect;
}
else if (timeDifference <= 0.125f)
{
postJudgeType = NoteJudgeType.Good;
}
else
{
postJudgeType = NoteJudgeType.Bad;
}
Debug.Log($"Hold Note Final Judge: {postJudgeType} at {triggerTime} of difference {timeDifference}");
NoteJudgeType finalJudge = NoteBase.GetLowerType(preJudgeType, postJudgeType);
if (finalJudge == NoteJudgeType.Perfect)
{
Perfect(triggerTime);
}
else if (finalJudge == NoteJudgeType.Good)
{
Good(triggerTime);
}
else if (finalJudge == NoteJudgeType.Bad)
{
Bad(triggerTime);
}
else if (finalJudge == NoteJudgeType.Miss)
{
Miss(triggerTime);
}
if (finalJudge != NoteJudgeType.Miss)
{
noteAudioSubmodule.PlayGeneralJudgeAudios();
}
}
2025-06-03 02:42:28 -04:00
}
public partial class Hold
{
public override void UpdateNoteInMovableTrack()
{
if (!isHolding && !isFinalJudged)
{
base.UpdateNoteInMovableTrack();
}
2025-07-21 05:42:20 -04:00
if (noteVisual is INoteVisualHold noteVisualHold)
2025-06-03 02:42:28 -04:00
{
noteVisualHold.UpdateHoldInMovableTrack();
}
}
public override void UpdateNoteInStaticTrack()
{
base.UpdateNoteInStaticTrack();
2025-07-21 05:42:20 -04:00
if (noteVisual is INoteVisualHold noteVisualHold)
2025-06-03 02:42:28 -04:00
{
noteVisualHold.UpdateHoldInStaticTrack();
}
}
2025-07-21 05:42:20 -04:00
protected override void RemoveFromCheckingList()
{
GameManager.instance.inputManager.checkingHoldList.Remove(this);
}
2025-06-03 02:42:28 -04:00
}
public partial class Hold
{
public override void SetDefaultSubmodules()
{
base.SetDefaultSubmodules();
noteAudioSubmodule = new NoteAudioSubmodule(this, "DefaultTap");
}
public override void SaveBM()
{
matchedBM = new Hold_BM(elementName, elementGuid, tags, parentElement.matchedBM as GameElement_BM, exactJudgeTime, holdEndTime);
}
}
2025-07-21 05:42:20 -04:00
public partial class Hold
{
public bool CheckJudgeAvailability(InputUnitTap inputUnitTap)
{
return !isFirstJudged && noteJudgeSubmodule.judgeUnitList.All(judgeUnit => judgeUnit.CheckJudgeAvailability(inputUnitTap));
}
public bool CheckJudgeAvailability(InputUnitTouch inputUnitTouch)
{
return isFirstJudged && noteJudgeSubmodule.judgeUnitList.All(judgeUnit => judgeUnit.CheckJudgeAvailability(inputUnitTouch));
}
}
2025-06-03 02:42:28 -04:00
public partial class Hold
{
protected override void Update()
{
2025-07-21 05:42:20 -04:00
float songTime = GameManager.instance.songTime;
if (!isFirstJudged && !isDuringJudging &&
songTime >= exactJudgeTime + judgeIntervals.beforeMiss.intervalStart &&
!GameManager.instance.inputManager.checkingHoldList.Contains(this))
2025-07-08 14:28:40 -04:00
{
2025-07-21 05:42:20 -04:00
isDuringJudging = true;
GameManager.instance.inputManager.checkingHoldList.Add(this);
2025-07-08 14:28:40 -04:00
}
2025-07-21 05:42:20 -04:00
if (!GameManager.instance.audioManager.isUpdating || isFinalJudged)
2025-06-03 02:42:28 -04:00
{
2025-07-21 05:42:20 -04:00
return;
2025-06-03 02:42:28 -04:00
}
if (isHolding)
{
holdingTime = songTime - exactJudgeTime;
2025-07-21 05:42:20 -04:00
bufferTimer = holdingBufferTime;
}
else if(isFirstJudged)
{
bufferTimer -= Time.deltaTime;
2025-06-03 02:42:28 -04:00
}
2025-07-21 05:42:20 -04:00
if (isOnTrack)
2025-06-03 02:42:28 -04:00
{
2025-07-21 05:42:20 -04:00
UpdateNoteInTrack();
2025-06-03 02:42:28 -04:00
}
2025-07-21 05:42:20 -04:00
if (isDuringJudging)
2025-06-03 02:42:28 -04:00
{
2025-07-21 05:42:20 -04:00
noteScreenPosition = GameManager.instance.cameraManager.gameCamera.gameCamera.WorldToScreenPoint(noteVisual.transform.position);
2025-06-03 02:42:28 -04:00
}
2025-07-21 05:42:20 -04:00
foreach (EffectBase e in noteVisual.effectSubmodule.effectCollection["Generate"])
2025-06-03 02:42:28 -04:00
{
2025-07-21 05:42:20 -04:00
e.UpdateEffect(exactJudgeTime);
2025-06-03 02:42:28 -04:00
}
2025-07-21 05:42:20 -04:00
foreach (EffectBase e in noteVisual.effectSubmodule.effectCollection["StartHold"])
{
e.UpdateEffect(exactJudgeTime);
}
2025-06-03 02:42:28 -04:00
2025-07-21 05:42:20 -04:00
foreach (EffectBase e in noteVisual.effectSubmodule.effectCollection["Holding"])
2025-06-03 02:42:28 -04:00
{
2025-07-21 05:42:20 -04:00
e.UpdateEffect(exactJudgeTime);
}
if (songTime > holdEndTime)
{
isHolding = false;
isFinalJudged = true;
ExecuteFinalJudge();
RemoveFromCheckingList();
}
2025-06-03 02:42:28 -04:00
2025-07-21 05:42:20 -04:00
if (isFirstJudged && bufferTimer < 0f)
{
isHolding = false;
isFinalJudged = true;
ExecuteFinalJudge();
RemoveFromCheckingList();
}
if (!isFirstJudged && GameManager.instance.songTime > exactJudgeTime + judgeIntervals.afterMiss)
{
Miss(exactJudgeTime + judgeIntervals.afterMiss);
isFirstJudged = true;
isFinalJudged = true;
RemoveFromCheckingList();
2025-06-03 02:42:28 -04:00
}
}
private void LateUpdate()
{
2025-07-21 05:42:20 -04:00
isHolding = false;
2025-06-03 02:42:28 -04:00
}
}
namespace Beatmap
{
public class Hold_BM : NoteBase_BM
{
public float holdEndTime;
public Hold_BM()
{
}
public Hold_BM(string elementName, Guid elementGuid, List<string> tags, GameElement_BM attachedElement, float exactJudgeTime, float holdEndTime)
: base(elementName, elementGuid, tags, attachedElement, exactJudgeTime)
{
this.holdEndTime = holdEndTime;
}
public override void ExecuteBM()
{
matchedElement = Hold.GenerateElement(elementName, elementGuid, tags, false,
GetElement(attachedElementGuid), exactJudgeTime, holdEndTime);
}
public override GameElement DuplicateBM(GameElement parent)
{
return Hold.GenerateElement(elementName, Guid.NewGuid(), tags, false, parent, exactJudgeTime, holdEndTime);
}
}
}
}