using System; using System.Collections; using System.Collections.Generic; using Dreamteck.Splines; using Sirenix.OdinInspector; using UnityEngine; namespace Ichni.RhythmGame { public abstract class NoteBase : BaseElement { [Title("Basic Info")] public float exactJudgeTime; [Title("Track Info")] public bool isOnTrack; public Track track; public SplinePositioner trackPositioner; [Title("NoteVisual")] public NoteVisualBase noteVisual; [Title("NoteEffect")] [Tooltip("生成Note时的特效")] public EffectSubmodule generateEffects; [Tooltip("Note被判定时的特效,不包括Miss")] public EffectSubmodule generalJudgeEffects; [Tooltip("Note被Perfect判定时的特效")] public EffectSubmodule perfectJudgeEffects; [Tooltip("Note被Good判定时的特效")] public EffectSubmodule goodJudgeEffects; [Tooltip("Note被Bad判定时的特效")] public EffectSubmodule badJudgeEffects; [Tooltip("Note未被判定时的特效,即Miss")] public EffectSubmodule missJudgeEffects; [Title("Judge Info")] public NoteJudgeSubmodule noteJudgeSubmodule; [Title("In-Game Info")] public Vector2 noteScreenPosition; public bool isJudged; /// /// 在MovableTrack上更新Note的位置,注意HoldNote需要重写这个方法 /// public virtual void UpdateNoteInMovableTrack() { trackPositioner.SetPercent((track.trackTimeSubmodule as TrackTimeSubmoduleMovable).GetTrackPercent(exactJudgeTime)); } /// /// 在StaticTrack上更新Note的位置,注意HoldNote需要重写这个方法 /// public virtual void UpdateNoteInStaticTrack() { float songTime = EditorManager.instance.songModule.songTime; TrackTimeSubmoduleStatic trackTimeSubmoduleStatic = track.trackTimeSubmodule as TrackTimeSubmoduleStatic; float startMove = exactJudgeTime - trackTimeSubmoduleStatic.trackTotalTime; float percent = AnimationCurveEvaluator.Evaluate(trackTimeSubmoduleStatic.animationCurveType, (songTime - startMove) / trackTimeSubmoduleStatic.trackTotalTime); percent = Mathf.Max(percent, 0); percent = Mathf.Min(percent, 1); trackPositioner.SetPercent(1 - percent); } public override void AfterInitialize() { generateEffects.effectList.ForEach(e => e.Recover()); generalJudgeEffects.effectList.ForEach(e => e.Recover()); perfectJudgeEffects.effectList.ForEach(e => e.Recover()); goodJudgeEffects.effectList.ForEach(e => e.Recover()); badJudgeEffects.effectList.ForEach(e => e.Recover()); missJudgeEffects.effectList.ForEach(e => e.Recover()); } private void Update() { if (isOnTrack) { if (track.trackTimeSubmodule is TrackTimeSubmoduleStatic) { UpdateNoteInStaticTrack(); } } float songTime = EditorManager.instance.songModule.songTime; if (isJudged && songTime < exactJudgeTime) { isJudged = false; } if (!isJudged && songTime >= exactJudgeTime) { if (!isJudged) { AudioSource.PlayClipAtPoint(EditorManager.instance.basePrefabs.tapNoteSound, Camera.main.transform.position, 1f); isJudged = true; } } foreach (var effect in generateEffects.effectList) { effect.UpdateEffect(); } foreach (var effect in perfectJudgeEffects.effectList) { effect.UpdateEffect(); } } public void ExecuteStartJudge() { } public void UpdateNoteInTrack() { if (isOnTrack && track.trackTimeSubmodule != null) { if (track.trackTimeSubmodule is TrackTimeSubmoduleMovable) { UpdateNoteInMovableTrack(); } else if (track.trackTimeSubmodule is TrackTimeSubmoduleStatic) { UpdateNoteInStaticTrack(); } } } } }