using System; using System.Collections; using System.Collections.Generic; using Ichni.RhythmGame.Beatmap; using Lean.Pool; using Sirenix.OdinInspector; using UniRx; using UnityEngine; using UnityEngine.Serialization; namespace Ichni.RhythmGame { public partial class Track : GameElement, IHaveTransformSubmodule, IHaveTimeDurationSubmodule { #region [暴露属性字段] Essential Configs public GameObject trackRenderer; #endregion #region [子模块接口] Submodules public TransformSubmodule transformSubmodule { get; set; } public TimeDurationSubmodule timeDurationSubmodule { get; set; } public TrackPathSubmodule trackPathSubmodule { get; set; } public TrackTimeSubmodule trackTimeSubmodule { get; set; } public TrackRendererSubmodule trackRendererSubmodule { get; set; } #endregion #region [生命周期] Lifecycle & Factory public static Track GenerateElement(string elementName, Guid id, List tags, bool isFirstGenerated, GameElement parentElement) { Track track = LeanPool.Spawn(GameManager.Instance.basePrefabs.track, parentElement.transform).GetComponent(); track.Initialize(elementName, id, tags, isFirstGenerated, parentElement); if (parentElement is ElementFolder folder) { folder.trackList.Add(track); } return track; } public override void SetDefaultSubmodules() { transformSubmodule = new TransformSubmodule(this); timeDurationSubmodule = new TimeDurationSubmodule(this); trackPathSubmodule = new TrackPathSubmodule(this, TrackSpaceType.CatmullRom, TrackSamplingType.TimeDistributed, false, false); trackTimeSubmodule = null; trackRendererSubmodule = null; } public override void AfterInitialize() { base.AfterInitialize(); GameManager.Instance.trackManager.RegisterTrack(this); if (trackPathSubmodule != null && trackPathSubmodule.pathNodeList.Count > 3) { trackPathSubmodule.ClosePath(); } if(trackRendererSubmodule != null) { trackRendererSubmodule.meshGenerator.autoUpdate = false; } } #endregion #region [轮询更新] Main Update public void ManualUpdate(float currentSongTime) { if (timeDurationSubmodule.CheckTimeInDuration(currentSongTime)) { (trackTimeSubmodule as TrackTimeSubmoduleMovable)?.UpdateTrackPart(currentSongTime); } } public void ManualLateUpdate() { if(trackPathSubmodule != null) trackPathSubmodule.refreshedThisFrame = false; } #endregion #region [行为重写] Behavior Overrides public override void Refresh() { base.Refresh(); trackPathSubmodule?.Refresh(); trackTimeSubmodule?.Refresh(); trackRendererSubmodule?.Refresh(); } public override void OnDelete() { GameManager.Instance.trackManager.UnregisterTrack(this); if (parentElement is ElementFolder folder) folder.trackList.Remove(this); } #endregion } #region [枚举定义] Enums public partial class Track { public enum TrackSpaceType { CatmullRom = 0, BSpline = 1, Linear = 3 } public enum TrackSamplingType { TimeDistributed = 0, DistanceDistributed = 1 } } #endregion }