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 { #region [暴露属性字段与接口] Exposed Fields & Interfaces public Hold hold { get; set; } public override Vector3 noteVisualPosition => headPoint.transform.position; public MeshGenerator meshGenerator; public SplinePositioner headPoint, tailPoint; #endregion #region [生命周期与工厂] Lifecycle & Factory 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; //meshGenerator.enabled = false; //extrude.Container = hold.track.trackPathSubmodule.container; } public override void AfterInitialize() { base.AfterInitialize(); Recover(); } #endregion #region [对象状态恢复] Status Recovery 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(); } } #endregion } public partial class DTMNoteVisualHold { #region [长条动态更新] Hold Updates 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 + hold.holdingTime); endPercent = trackTimeSubmoduleMovable.GetTrackPercent(hold.holdEndTime); hold.trackPositioner.SetPercent(startPercent); meshGenerator.SetClipRange(startPercent, endPercent); //Debug.Log("Range: " + startPercent + " - " + endPercent); //extrude.Range = new Vector2(startPercent, endPercent); headPoint.SetPercent(startPercent); tailPoint.SetPercent(endPercent); } public void UpdateHoldInStaticTrack() { //throw new NotImplementedException(); } #endregion #region [变化监听与重置] Transform & Refresh Overrides public void UpdateTransform(bool refreshAll = true) { bool willRefresh = false; if (transformSubmodule.positionDirtyMark) { transformSubmodule.currentPosition = transformSubmodule.originalPosition + transformSubmodule.positionOffset; transformSubmodule.positionDirtyMark = false; willRefresh = true; transformSubmodule.positionOffset = Vector3.zero; //extrude.transform.localPosition = Vector3.zero - hold.transform.localPosition; //extrude.transform.localEulerAngles = Vector3.zero - hold.transform.localEulerAngles; } if (refreshAll && willRefresh) { Refresh(); } } public override void Refresh() { base.Refresh(); 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; } #endregion } }