using System; using System.Collections; using System.Collections.Generic; using Dreamteck.Splines; using Ichni.RhythmGame.Beatmap; using Unity.VisualScripting; using UnityEngine; namespace Ichni.RhythmGame { public partial class TrackPathSubmodule : TrackSubmodule { public SplineComputer path; public List pathNodeList; public Track.TrackSpaceType trackSpaceType; public Track.TrackSamplingType trackSamplingType; public bool isClosed; public bool refreshedThisFrame = false; public bool isShowingDisplay; public TrackPathSubmodule(Track track, Track.TrackSpaceType trackSpaceType, Track.TrackSamplingType trackSamplingType, bool isClosed, bool isShowingDisplay) : base(track) { this.path = track.AddComponent(); this.pathNodeList = new List(); this.trackSpaceType = trackSpaceType; this.trackSamplingType = trackSamplingType; this.isClosed = isClosed; this.path.sampleRate = 16; this.path.updateMode = SplineComputer.UpdateMode.LateUpdate; SetUpSplineComputer(this.trackSpaceType, this.trackSamplingType); //闭合路径在PathNode生成时执行,在初始化的情况下,PathNode数量为0,不会执行闭合操作 this.isShowingDisplay = isShowingDisplay; if (!HaveSameSubmodule) { this.track.trackPathSubmodule = this; } } } public partial class TrackPathSubmodule { private void SetUpSplineComputer(Track.TrackSpaceType trackSpaceType, Track.TrackSamplingType trackSamplingType) { path.type = (Spline.Type)trackSpaceType; path.sampleMode = (SplineComputer.SampleMode)(int)trackSamplingType; path.space = SplineComputer.Space.Local; } public void ClosePath() { if (isClosed) { path.Close(); } else { path.Break(); } } public void SetTrackSpaceType(int spaceType) { int SpaceType = spaceType; if (spaceType == 2) SpaceType++; trackSpaceType = (Track.TrackSpaceType)SpaceType; path.type = (Spline.Type)SpaceType; } public void SetPathNode(PathNode point) { path.SetPoint(point.index, point.node, SplineComputer.Space.Local); } public override void Refresh() { if(refreshedThisFrame) return; refreshedThisFrame = true; SetTrackSpaceType((int)trackSpaceType); SetUpSplineComputer(trackSpaceType, trackSamplingType); foreach (var pathNode in pathNodeList) { SetPathNode(pathNode); } ClosePath(); path.RebuildImmediate(true, true); } } public partial class TrackPathSubmodule { public override void SaveBM() { matchedBM = new TrackPathSubmodule_BM(attachedGameElement, this); } } namespace Beatmap { public class TrackPathSubmodule_BM : Submodule_BM { public Track.TrackSpaceType trackSpaceType; public Track.TrackSamplingType trackSamplingType; public bool isClosed; public bool isShowingDisplay; public TrackPathSubmodule_BM() { } public TrackPathSubmodule_BM(GameElement attachedElement, TrackPathSubmodule trackPathSubmodule) : base( attachedElement) { this.trackSpaceType = trackPathSubmodule.trackSpaceType; this.trackSamplingType = trackPathSubmodule.trackSamplingType; this.isClosed = trackPathSubmodule.isClosed; this.isShowingDisplay = trackPathSubmodule.isShowingDisplay; } public override void ExecuteBM() { attachedElement = GameElement_BM.GetElement(attachedElementGuid); Track track = attachedElement as Track; track.trackPathSubmodule = new TrackPathSubmodule(track, trackSpaceType, trackSamplingType, isClosed, isShowingDisplay); } } } }