132 lines
4.4 KiB
C#
132 lines
4.4 KiB
C#
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, IScheduledElement
|
||
{
|
||
#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<string> tags, bool isFirstGenerated, GameElement parentElement)
|
||
{
|
||
Track track = LeanPool.Spawn(GameManager.Instance.basePrefabs.track, parentElement.transform).GetComponent<Track>();
|
||
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();
|
||
|
||
// 保留 TrackManager 注册以维持 ManualLateUpdate 的 refreshedThisFrame 清除逻辑
|
||
GameManager.Instance.trackManager.RegisterTrack(this);
|
||
// 注册调度器 Phase 4(TrackCore)驱动 ManualUpdate
|
||
CoreServices.UpdateScheduler.Register(UpdatePhase.TrackCore, this);
|
||
CoreServices.UpdateScheduler.RegisterTrackSpline(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;
|
||
}
|
||
|
||
#region [IScheduledElement] Scheduler Interface
|
||
public void ScheduledUpdate(UpdatePhase phase, float songTime)
|
||
{
|
||
ManualUpdate(songTime);
|
||
}
|
||
|
||
public bool IsScheduledActive => isActiveAndEnabled;
|
||
#endregion
|
||
#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);
|
||
CoreServices.UpdateScheduler.Unregister(UpdatePhase.TrackCore, this);
|
||
CoreServices.UpdateScheduler.UnregisterTrackSpline(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
|
||
|
||
} |