using System; using System.Collections.Generic; using System.Linq; using Dreamteck.Splines; using Ichni.RhythmGame.Beatmap; using Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse.Beatmap; using UniRx; using UnityEngine; namespace Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse { public partial class DTMNoteVisualHold : DTMNoteVisual, INoteVisualHold, IHaveTransformSubmodule { public Hold hold { get; set; } public MeshGenerator meshGenerator; public SplinePositioner headPoint, tailPoint; public override Vector3 noteVisualPosition => headPoint.transform.position; public new static DTMNoteVisualHold GenerateElement(string elementName, Guid id, List tags, bool isFirstGenerated, string themeBundleName, string objectName, GameElement parentElement, bool isHighlighted) { DTMNoteVisualHold noteVisualHold = NoteVisualBase.GenerateElement(elementName, id, tags, isFirstGenerated, themeBundleName, objectName, parentElement, isHighlighted).GetComponent(); return noteVisualHold; } public override void FirstSetUpObject(bool isFirstGenerated) { NoteBase note = parentElement as NoteBase; if (note == null) throw new System.Exception("NoteVisual只能生成在Note下。"); if (!note.isOnTrack) throw new System.Exception("这种HoldNoteVisual只能生成在Track上。"); this.note = note; note.noteVisual = this; this.hold = note as Hold; this.headPoint = notePartList[0].GetComponent(); this.meshGenerator = notePartList[1].GetComponent(); this.tailPoint = notePartList[2].GetComponent(); this.hold.trackPositioner.autoUpdate = false; headPoint.spline = hold.track.trackPathSubmodule.path; meshGenerator.spline = hold.track.trackPathSubmodule.path; tailPoint.spline = hold.track.trackPathSubmodule.path; TrackTimeSubmoduleMovable trackTimeSubmoduleMovable = hold.track.trackTimeSubmodule as TrackTimeSubmoduleMovable; float startPercent = trackTimeSubmoduleMovable.GetTrackPercent(hold.exactJudgeTime); float endPercent = trackTimeSubmoduleMovable.GetTrackPercent(hold.holdEndTime); hold.trackPositioner.SetPercent(startPercent); meshGenerator.SetClipRange(startPercent, endPercent); headPoint.SetPercent(startPercent); tailPoint.SetPercent(endPercent); if (isFirstGenerated) { note.noteJudgeSubmodule.AddJudgeUnit("TouchArea"); effectSubmodule.effectCollection["Generate"].Add(new DTMNoteGenerateExtend(this, 1f, 0.5f)); effectSubmodule.effectCollection["Perfect"].Add(new DTMNotePerfectBurst(this)); effectSubmodule.effectCollection["Good"].Add(new DTMNoteGoodBurst(this)); effectSubmodule.effectCollection["Bad"].Add(new DTMNoteBadBurst(this)); effectSubmodule.effectCollection["Miss"].Add(new DTMNoteMissTransparent(this, 0.2f)); effectSubmodule.effectCollection["Holding"].Add(new DTMNoteHoldingBreath(this)); } // judgeEffect.transform.position = tailPoint.transform.position; } public override void AfterInitialize() { base.AfterInitialize(); Recover(); } public override void Recover() { foreach (GameObject part in notePartList) { Renderer rend = part.GetComponent(); if (rend != null) { rend.materials[0].SetFloat("_MainAlpha", 1f); rend.materials[1].SetFloat("_MainAlpha", 1f); note.track.trackPathSubmodule.path.RebuildImmediate(); } } foreach (EffectBase effect in effectSubmodule.effectCollection["Generate"]) { effect.Recover(); } foreach (EffectBase effect in effectSubmodule.effectCollection["Holding"]) { effect.Recover(); } } public override void Refresh() { base.Refresh(); foreach (EffectBase effect in effectSubmodule.effectCollection["Generate"]) { if (effect.nowEffectState == EffectBase.EffectState.Middle) { effect.Recover(); } } } } public partial class DTMNoteVisualHold { public override void SaveBM() { matchedBM = new DTMNoteVisualHold_BM(elementName, elementGuid, tags, themeBundleName, objectName, parentElement.matchedBM as GameElement_BM, isHighlighted); } private float startPercent, endPercent; public void UpdateHoldInMovableTrack() { if (effectSubmodule.effectCollection["Generate"].Any(e => e.nowEffectState == EffectBase.EffectState.Middle)) { return; } TrackTimeSubmoduleMovable trackTimeSubmoduleMovable = hold.track.trackTimeSubmodule as TrackTimeSubmoduleMovable; startPercent = trackTimeSubmoduleMovable.GetTrackPercent(hold.exactJudgeTime); endPercent = trackTimeSubmoduleMovable.GetTrackPercent(hold.holdEndTime); if (hold.isHolding) { startPercent = trackTimeSubmoduleMovable.GetTrackPercent(hold.exactJudgeTime + hold.holdingTime); endPercent = trackTimeSubmoduleMovable.GetTrackPercent(hold.holdEndTime); } else if (hold.isFinalJudged) { startPercent = trackTimeSubmoduleMovable.GetTrackPercent(hold.holdEndTime); endPercent = trackTimeSubmoduleMovable.GetTrackPercent(hold.holdEndTime); } hold.trackPositioner.SetPercent(startPercent); meshGenerator.SetClipRange(startPercent, endPercent); headPoint.SetPercent(startPercent); tailPoint.SetPercent(endPercent); } public void UpdateHoldInStaticTrack() { //throw new NotImplementedException(); } public void SetTransformObserver() { Observable.EveryUpdate().Subscribe(_ => { if (transformSubmodule == null) { return; } bool willRefresh = false; if (transformSubmodule.positionDirtyMark) { transformSubmodule.currentPosition = transformSubmodule.originalPosition + transformSubmodule.positionOffset; Vector2 posOffset = new Vector2(transformSubmodule.currentPosition.x, transformSubmodule.currentPosition.y); hold.trackPositioner.motion.offset = posOffset; meshGenerator.offset = posOffset; headPoint.motion.offset = posOffset; tailPoint.motion.offset = posOffset; transformSubmodule.positionDirtyMark = false; willRefresh = true; transformSubmodule.positionOffset = Vector3.zero; } if (willRefresh) { Refresh(); } }).AddTo(gameObject); } } namespace Beatmap { public class DTMNoteVisualHold_BM : DTMNoteVisual_BM { public DTMNoteVisualHold_BM() { } public DTMNoteVisualHold_BM(string elementName, Guid id, List tags, string themeBundleName, string objectName, GameElement_BM parent, bool isHighlighted) : base(elementName, id, tags, parent, themeBundleName, objectName, isHighlighted) { } public override void ExecuteBM() { matchedElement = DTMNoteVisualHold.GenerateElement(elementName, elementGuid, tags, false, themeBundleName, objectName, GetElement(attachedElementGuid), isHighlighted); } public override GameElement DuplicateBM(GameElement parent) { return DTMNoteVisualHold.GenerateElement(elementName, Guid.NewGuid(), tags, false, themeBundleName, objectName, parent, isHighlighted); } } } }