using Godot; using Onrinto.Chart; public partial class GameManager : Node3D { [Export] public float VisibleDistance = 150.0f; [Export] public float PlayerSpeed = 1.5f; public TrackData CurrentTrack { get; set; } public static GameManager Instance { get; private set; } public float CurrentAbsoluteSpeed { get; private set; } public float FinalSpeed => CurrentAbsoluteSpeed * PlayerSpeed; public float CurrentAbsZ { get; private set; } private int absoluteSpeedPointIndexArrow = 0; private void UpdateAbsoluteState(double time) { var points = CurrentTrack.AbsoluteSpeedPoints; if(points == null || points.Count == 0) return; double firstPointTime = CurrentTrack.TickToSeconds(points[0].Tick); if(time < firstPointTime) { CurrentAbsoluteSpeed = points[0].Speed; return; } if(absoluteSpeedPointIndexArrow > 0 && time < CurrentTrack.TickToSeconds(points[absoluteSpeedPointIndexArrow].Tick)) { absoluteSpeedPointIndexArrow = 0; } for(int i = absoluteSpeedPointIndexArrow; i < points.Count - 1; i++) { double pointTime_from = CurrentTrack.TickToSeconds(points[i].Tick); double pointTime_to = CurrentTrack.TickToSeconds(points[i + 1].Tick); if(time >= pointTime_from && time < pointTime_to) { absoluteSpeedPointIndexArrow = i; if(points[i].IsLinear) { if (pointTime_to <= pointTime_from) { CurrentAbsoluteSpeed = points[i].Speed; } else { double t = (time - pointTime_from) / (pointTime_to - pointTime_from); CurrentAbsoluteSpeed = Mathf.Lerp(points[i].Speed, points[i + 1].Speed, (float)t); } } else { CurrentAbsoluteSpeed = points[i].Speed; } return; } } absoluteSpeedPointIndexArrow = points.Count - 1; CurrentAbsoluteSpeed = points[^1].Speed; } // Called when the node enters the scene tree for the first time. public override void _Ready() { if (Instance != null){ QueueFree(); return; } Instance = this; ProcessPriority = -100; } // Called every frame. 'delta' is the elapsed time since the previous frame. public override void _Process(double delta) { double tNow = MusicClock.Instance.CurrentTime; if(CurrentTrack == null) return; UpdateAbsoluteState(tNow); CurrentAbsZ = CurrentTrack.GetZ(tNow, CurrentTrack.RelativeSpeedPoints, CurrentTrack.RelativeZTable); } }