Prepwork for seeking + tempo change fixes

TODO: make playing after seeking function (I'll need help with the offset stuff so if anyone can push to this branch please do)
This commit is contained in:
minenice55 2022-06-05 23:13:31 -04:00
parent 52ecce8c3e
commit bdf76f3770
4 changed files with 62 additions and 12 deletions

View file

@ -85,6 +85,8 @@ namespace HeavenStudio
bool negativeOffset = firstBeatOffset < 0f; bool negativeOffset = firstBeatOffset < 0f;
bool negativeStartTime = false; bool negativeStartTime = false;
Debug.Log("starting playback @ beat " + beat);
var startPos = GetSongPosFromBeat(beat); var startPos = GetSongPosFromBeat(beat);
if (negativeOffset) if (negativeOffset)
{ {
@ -99,8 +101,11 @@ namespace HeavenStudio
else else
time = startPos; time = startPos;
} }
songPosBeat = time / secPerBeat; //TODO: make this take into account past tempo changes
songPosBeat = time / secPerBeat;
songPositionInBeats = songPosBeat;
Debug.Log("offset starting playback @ beat " + songPosBeat);
isPlaying = true; isPlaying = true;
isPaused = false; isPaused = false;
@ -234,7 +239,41 @@ namespace HeavenStudio
public float GetSongPosFromBeat(float beat) public float GetSongPosFromBeat(float beat)
{ {
return secPerBeat * beat; Beatmap chart = GameManager.instance.Beatmap;
SetBpm(chart.bpm);
//initial counter
float counter = 0f;
//time of last tempo change, to know how much to add to counter
float lastTempoChangeBeat = 0f;
//iterate over all tempo changes, adding to counter
List<Beatmap.TempoChange> tempoChanges = chart.tempoChanges;
tempoChanges.Sort((x, y) => x.beat.CompareTo(y.beat)); //sorts all tempo changes by ascending time (GameManager already does this but juste en cas...)
foreach (var t in tempoChanges)
{
if (t.beat > beat)
{
// this tempo change is past our requested time, abort
break;
}
// Debug.Log("tempo change at " + t.beat);
counter += (t.beat - lastTempoChangeBeat) * secPerBeat;
// Debug.Log("counter is now " + counter);
// now update to new bpm
SetBpm(t.tempo);
lastTempoChangeBeat = t.beat;
}
//passed all past tempo changes, now extrapolate from last tempo change until requested position
counter += (beat - lastTempoChangeBeat) * secPerBeat;
// Debug.Log("GetSongPosFromBeat returning " + counter);
return counter - firstBeatOffset;
} }
// convert real seconds to beats // convert real seconds to beats
@ -257,6 +296,8 @@ namespace HeavenStudio
public float SongLengthInBeats() public float SongLengthInBeats()
{ {
if (!musicSource.clip) return 0; if (!musicSource.clip) return 0;
//TODO: make this take into account past tempo changes
return musicSource.clip.length / secPerBeat; return musicSource.clip.length / secPerBeat;
} }

View file

@ -151,7 +151,7 @@ namespace HeavenStudio
// LateUpdate works a bit better(?) but causes some bugs (like issues with bop animations). // LateUpdate works a bit better(?) but causes some bugs (like issues with bop animations).
private void Update() private void Update()
{ {
if (Beatmap.entities.Count < 1) if (BeatmapEntities() < 1) //bruh really you forgot to ckeck tempo changes
return; return;
if (!Conductor.instance.isPlaying) if (!Conductor.instance.isPlaying)
return; return;
@ -197,9 +197,11 @@ namespace HeavenStudio
if (currentTempoEvent < Beatmap.tempoChanges.Count && currentTempoEvent >= 0) if (currentTempoEvent < Beatmap.tempoChanges.Count && currentTempoEvent >= 0)
{ {
// Debug.Log("Checking Tempo Change at " + tempoChanges[currentTempoEvent] + ", current beat " + Conductor.instance.songPositionInBeats);
if (Conductor.instance.songPositionInBeats >= tempoChanges[currentTempoEvent]) if (Conductor.instance.songPositionInBeats >= tempoChanges[currentTempoEvent])
{ {
Conductor.instance.songBpm = Beatmap.tempoChanges[currentTempoEvent].tempo; // Debug.Log("Tempo Change at " + Conductor.instance.songPositionInBeats + " of bpm " + Beatmap.tempoChanges[currentTempoEvent].tempo);
Conductor.instance.SetBpm(Beatmap.tempoChanges[currentTempoEvent].tempo);
Conductor.instance.timeSinceLastTempoChange = Time.time; Conductor.instance.timeSinceLastTempoChange = Time.time;
currentTempoEvent++; currentTempoEvent++;
} }
@ -325,9 +327,20 @@ namespace HeavenStudio
if (Beatmap.tempoChanges.Count > 0) if (Beatmap.tempoChanges.Count > 0)
{ {
currentTempoEvent = 0;
List<float> tempoChanges = Beatmap.tempoChanges.Select(c => c.beat).ToList(); List<float> tempoChanges = Beatmap.tempoChanges.Select(c => c.beat).ToList();
currentTempoEvent = tempoChanges.IndexOf(Mathp.GetClosestInList(tempoChanges, beat)); //for tempo changes, just go over all of em until the last one we pass
for (int t = 0; t < tempoChanges.Count; t++)
{
Debug.Log("checking tempo event " + t + " against beat " + beat + "( tc beat " + tempoChanges[t] + ")");
if (tempoChanges[t] > beat)
{
break;
}
currentTempoEvent = t;
}
Debug.Log("currentTempoEvent is now " + currentTempoEvent);
} }
} }

View file

@ -129,11 +129,7 @@ namespace HeavenStudio.Editor.Track
} }
private void AddTempoChange(bool create, Beatmap.TempoChange tempoChange_ = null) private void AddTempoChange(bool create, Beatmap.TempoChange tempoChange_ = null)
{ {
// TEMP: DISABLED UNTIL CRITICAL FIXES
if (create)
return;
GameObject tempoChange = Instantiate(RefTempoChange.gameObject, this.transform); GameObject tempoChange = Instantiate(RefTempoChange.gameObject, this.transform);
tempoChange.transform.GetChild(0).GetComponent<Image>().color = EditorTheme.theme.properties.TempoLayerCol.Hex2RGB(); tempoChange.transform.GetChild(0).GetComponent<Image>().color = EditorTheme.theme.properties.TempoLayerCol.Hex2RGB();

View file

@ -296,7 +296,7 @@ namespace HeavenStudio.Editor.Track
if (movingPlayback) if (movingPlayback)
{ {
RectTransformUtility.ScreenPointToLocalPointInRectangle(TimelineContent, Input.mousePosition, Editor.instance.EditorCamera, out lastMousePos); RectTransformUtility.ScreenPointToLocalPointInRectangle(TimelineContent, Input.mousePosition, Editor.instance.EditorCamera, out lastMousePos);
TimelineSlider.localPosition = new Vector3(Mathf.Clamp(Mathp.Round2Nearest(lastMousePos.x + 0.12f, Timeline.SnapInterval()), 0, Mathf.Infinity), TimelineSlider.transform.localPosition.y); TimelineSlider.localPosition = new Vector3(Mathf.Max(Mathp.Round2Nearest(lastMousePos.x + 0.12f, Timeline.SnapInterval()), 0), TimelineSlider.transform.localPosition.y);
if (TimelineSlider.localPosition.x != lastBeatPos) if (TimelineSlider.localPosition.x != lastBeatPos)
Conductor.instance.SetBeat(TimelineSlider.transform.localPosition.x); Conductor.instance.SetBeat(TimelineSlider.transform.localPosition.x);