Auto-Swing (#827)

* BurstLinq

make BGM resync when changing pitch (to test)

* autoswing

some game implementations, most games already work fine

* more game tweaks

* 16th note swing

more game fixes
make pitch change resync optional in the API

* suppress some common warnings

* Update Credits.txt
This commit is contained in:
minenice55
2024-04-07 00:54:06 -04:00
committed by minenice55
parent 47905fffc2
commit a3f33e5279
49 changed files with 2372 additions and 242 deletions

View File

@ -15,6 +15,7 @@ using HeavenStudio.StudioDance;
using Jukebox;
using UnityEditor;
using System.Linq;
using BurstLinq;
namespace HeavenStudio.Editor
{
@ -269,6 +270,11 @@ namespace HeavenStudio.Editor
public void SelectMusic()
{
if (Timeline.instance != null)
Timeline.instance?.Stop(0);
else
GameManager.instance.Stop(0);
var extensions = new[]
{
new ExtensionFilter("Music Files", "mp3", "ogg", "wav", "aiff", "aif", "aifc")

View File

@ -160,6 +160,7 @@ namespace HeavenStudio.Editor.Track
lastTempo /= 2f;
}
RiqEntity tempoC = GameManager.instance.Beatmap.AddNewTempoChange(Timeline.instance.MousePos2BeatSnap, lastTempo);
tempoC.CreateProperty("swingDivision", 1f);
tempoTimelineObj.chartEntity = tempoC;
CommandManager.Instance.AddCommand(new Commands.AddMarker(tempoC, tempoC.guid, HoveringTypes.TempoChange));
}

View File

@ -14,6 +14,9 @@ public class TempoDialog : Dialog
[SerializeField] Button deleteButton;
[SerializeField] TMP_InputField tempoInput;
[SerializeField] TMP_InputField swingInput;
[SerializeField] Slider swingSlider;
[SerializeField] Toggle swingDivisionToggle;
public void SwitchTempoDialog()
{
@ -28,6 +31,9 @@ public class TempoDialog : Dialog
Editor.instance.inAuthorativeMenu = true;
ResetAllDialogs();
dialog.SetActive(true);
swingSlider.maxValue = 0.25f;
swingSlider.minValue = 0;
}
}
@ -45,6 +51,10 @@ public class TempoDialog : Dialog
deleteButton.gameObject.SetActive(!tempoObj.first);
tempoInput.text = tempoObj.chartEntity["tempo"].ToString("F");
swingInput.text = (tempoObj.chartEntity["swing"] * 400).ToString("F");
swingSlider.value = tempoObj.chartEntity["swing"];
swingDivisionToggle.isOn = tempoObj.chartEntity["swingDivision"] != 1f;
}
public void DeleteTempo()
@ -86,4 +96,33 @@ public class TempoDialog : Dialog
tempoInput.text = tempoObj.chartEntity["tempo"].ToString("F");
}
}
public void SwingSliderUpdate()
{
if (tempoObj != null)
{
tempoObj.SetSwing(System.MathF.Round(swingSlider.value, 4));
swingInput.text = (tempoObj.chartEntity["swing"] * 400).ToString("F");
swingSlider.value = tempoObj.chartEntity["swing"];
}
}
public void SetSwing()
{
if (tempoObj != null)
{
float swing = float.Parse(swingInput.text);
tempoObj.SetSwing(swing * 0.25f / 100f);
swingInput.text = (tempoObj.chartEntity["swing"] * 400).ToString("F");
swingSlider.value = tempoObj.chartEntity["swing"];
}
}
public void SwingDivisionToggle()
{
if (tempoObj != null)
{
tempoObj.SetSwingDivision(swingDivisionToggle.isOn);
}
}
}

View File

@ -62,6 +62,18 @@ namespace HeavenStudio.Editor.Track
SetX(chartEntity);
}
public void SetSwing(float swing)
{
chartEntity["swing"] = Mathf.Clamp(swing, 0, 0.5f);
UpdateTempo();
}
public void SetSwingDivision(bool sixteenth)
{
chartEntity["swingDivision"] = sixteenth ? 0.5f : 1f;
UpdateTempo();
}
public override void Init()
{
UpdateTempo();

View File

@ -9,6 +9,7 @@ using TMPro;
using Jukebox;
using Newtonsoft.Json;
using System.Linq;
using BurstLinq;
using HeavenStudio.Util;
@ -475,7 +476,7 @@ namespace HeavenStudio.Editor.Track
if (Conductor.instance.metronome)
{
var startBeat = Mathf.FloorToInt(Conductor.instance.songPositionInBeats - 0.5f);
var nm = Conductor.instance.GetLoopPositionFromBeat(0.5f, 1f);
var nm = Conductor.instance.GetLoopPositionFromBeat(0.5f, 1f, ignoreSwing: false);
var loop = (startBeat % 2 == 0) ? Mathf.SmoothStep(-1.1f, 1f, nm) : Mathf.SmoothStep(1f, -1f, nm);
rot = loop * 45f;
@ -630,7 +631,7 @@ namespace HeavenStudio.Editor.Track
{
TimelinePlaybackBeat.text = $"Beat {string.Format("{0:0.000}", PlaybackBeat)}";
if (TimelineSongPosLine != null)
if (TimelineSongPosLine != null && !Conductor.instance.WaitingForDsp)
{
TimelineSongPosLine.transform.localPosition = new Vector3(Conductor.instance.songPositionInBeats * PixelsPerBeat, TimelineSongPosLine.transform.localPosition.y);
}
@ -655,13 +656,13 @@ namespace HeavenStudio.Editor.Track
{
if (!Conductor.instance.isPlaying)
{
if (TimelineSongPosLine == null)
if (Conductor.instance.isPaused)
{
Play(false, PlaybackBeat);
Play(false, Conductor.instance.songPositionInBeats);
}
else
{
Play(false, Conductor.instance.songPositionInBeats);
Play(false, PlaybackBeat);
}
}
else if (!Conductor.instance.isPaused)
@ -673,16 +674,14 @@ namespace HeavenStudio.Editor.Track
public void Play(bool fromStart, float time)
{
// if (fromStart) Stop();
GameManager.instance.SafePlay(time, 0, false);
if (!Conductor.instance.isPaused)
{
TimelineSongPosLine = Instantiate(TimelineSongPosLineRef, TimelineSongPosLineRef.parent).GetComponent<RectTransform>();
TimelineSongPosLine.gameObject.SetActive(true);
TimelineSongPosLine.transform.localPosition = new Vector3(time * PixelsPerBeat, TimelineSongPosLine.transform.localPosition.y);
}
GameManager.instance.SafePlay(time, 0, false);
SetTimeButtonColors(false, true, true);
}

View File

@ -5,6 +5,7 @@ using UnityEngine.Pool;
using Jukebox;
using System.Linq;
using BurstLinq;
namespace HeavenStudio.Editor.Track
{