autoswing

some game implementations, most games already work fine
This commit is contained in:
minenice55 2024-04-05 23:52:45 -04:00
parent 317b3413f3
commit b88280cfe3
17 changed files with 1571 additions and 145 deletions

File diff suppressed because it is too large Load diff

View file

@ -23,11 +23,11 @@ namespace HeavenStudio
// Song beats per minute // Song beats per minute
// This is determined by the song you're trying to sync up to // This is determined by the song you're trying to sync up to
public float songBpm; public float songBpm { get; private set; }
// The number of seconds for each song beat // The number of seconds for each song beat
public float secPerBeat => (float)secPerBeatAsDouble; public float secPerBeat => (float)secPerBeatAsDouble;
public double secPerBeatAsDouble; public double secPerBeatAsDouble { get; private set; }
// The number of seconds for each song beat, inversely scaled to song pitch (higer pitch = shorter time) // The number of seconds for each song beat, inversely scaled to song pitch (higer pitch = shorter time)
public float pitchedSecPerBeat => (float)pitchedSecPerBeatAsDouble; public float pitchedSecPerBeat => (float)pitchedSecPerBeatAsDouble;
@ -39,9 +39,11 @@ namespace HeavenStudio
public double songPositionAsDouble => songPos; public double songPositionAsDouble => songPos;
// Current song position, in beats // Current song position, in beats
public double songPosBeat; // for Conductor use only public double songPosBeat { get; private set; }
public float songPositionInBeats => (float)songPosBeat; public float songPositionInBeats => (float)songPositionInBeatsAsDouble;
public double songPositionInBeatsAsDouble => songPosBeat; public double songPositionInBeatsAsDouble { get; private set; }
public float unswungSongPositionInBeats => (float)songPosBeat;
public double unswungSongPositionInBeatsAsDouble => songPosBeat;
// Current time of the song // Current time of the song
private double time; private double time;
@ -80,7 +82,7 @@ namespace HeavenStudio
// Metronome tick sound enabled // Metronome tick sound enabled
public bool metronome = false; public bool metronome = false;
Util.Sound metronomeSound; Util.MultiSound metronomeSound;
private int _metronomeTally = 0; private int _metronomeTally = 0;
// pitch values // pitch values
@ -99,7 +101,7 @@ namespace HeavenStudio
if (isPaused || deferTimeKeeping) return; if (isPaused || deferTimeKeeping) return;
if (pitch != 0 && pitch != timelinePitch) if (pitch != 0 && pitch != timelinePitch)
{ {
Debug.Log("added pitch change " + pitch * minigamePitch + " at " + absTime); // Debug.Log("added pitch change " + pitch * minigamePitch + " at " + absTime);
addedPitchChanges.Add(new AddedPitchChange { time = absTime, pitch = pitch * minigamePitch }); addedPitchChanges.Add(new AddedPitchChange { time = absTime, pitch = pitch * minigamePitch });
} }
@ -107,19 +109,22 @@ namespace HeavenStudio
if (musicSource != null && musicSource.clip != null) if (musicSource != null && musicSource.clip != null)
{ {
musicSource.pitch = SongPitch; musicSource.pitch = SongPitch;
if (isPlaying)
{
time = MapTimeToPitchChanges(absTime + absTimeAdjust); time = MapTimeToPitchChanges(absTime + absTimeAdjust);
songPos = startPos + time; songPos = startPos + time;
songPosBeat = GetBeatFromSongPos(songPos); songPosBeat = GetBeatFromSongPos(songPos);
SeekMusicToTime(songPos, firstBeatOffset); SeekMusicToTime(songPos, firstBeatOffset);
} }
} }
}
public void SetMinigamePitch(float pitch) public void SetMinigamePitch(float pitch)
{ {
if (isPaused || deferTimeKeeping || !isPlaying) return; if (isPaused || deferTimeKeeping || !isPlaying) return;
if (pitch != 0 && pitch != minigamePitch) if (pitch != 0 && pitch != minigamePitch)
{ {
Debug.Log("added pitch change " + pitch * timelinePitch + " at " + absTime); // Debug.Log("added pitch change " + pitch * timelinePitch + " at " + absTime);
addedPitchChanges.Add(new AddedPitchChange { time = absTime, pitch = pitch * timelinePitch }); addedPitchChanges.Add(new AddedPitchChange { time = absTime, pitch = pitch * timelinePitch });
} }
@ -127,12 +132,15 @@ namespace HeavenStudio
if (musicSource != null && musicSource.clip != null) if (musicSource != null && musicSource.clip != null)
{ {
musicSource.pitch = SongPitch; musicSource.pitch = SongPitch;
if (isPlaying)
{
time = MapTimeToPitchChanges(absTime + absTimeAdjust); time = MapTimeToPitchChanges(absTime + absTimeAdjust);
songPos = startPos + time; songPos = startPos + time;
songPosBeat = GetBeatFromSongPos(songPos); songPosBeat = GetBeatFromSongPos(songPos);
SeekMusicToTime(songPos, firstBeatOffset); SeekMusicToTime(songPos, firstBeatOffset);
} }
} }
}
void Awake() void Awake()
{ {
@ -170,6 +178,8 @@ namespace HeavenStudio
{ {
deferTimeKeeping = true; deferTimeKeeping = true;
songPosBeat = beat; songPosBeat = beat;
absTime = 0;
startTime = DateTime.Now;
} }
public void Play(double beat) public void Play(double beat)
@ -224,6 +234,7 @@ namespace HeavenStudio
_metronomeTally = 0; _metronomeTally = 0;
startTime = DateTime.Now; startTime = DateTime.Now;
absTime = 0;
absTimeAdjust = 0; absTimeAdjust = 0;
deferTimeKeeping = musicSource.clip != null; deferTimeKeeping = musicSource.clip != null;
@ -241,7 +252,8 @@ namespace HeavenStudio
{ {
deferTimeKeeping = false; deferTimeKeeping = false;
// Debug.Log($"dsptime: {dsp}, deferred timekeeping for {DateTime.Now - startTime} seconds (delta dsp {dsp - dspStart})"); // Debug.Log($"dsptime: {dsp}, deferred timekeeping for {DateTime.Now - startTime} seconds (delta dsp {dsp - dspStart})");
startTime += TimeSpan.FromSeconds(dsp - dspStart); startTime = DateTime.Now;
absTime = 0;
absTimeAdjust = 0; absTimeAdjust = 0;
dspStart = dsp; dspStart = dsp;
} }
@ -400,6 +412,7 @@ namespace HeavenStudio
songPos = startPos + time; songPos = startPos + time;
songPosBeat = GetBeatFromSongPos(songPos); songPosBeat = GetBeatFromSongPos(songPos);
songPositionInBeatsAsDouble = GetSwungBeat(songPosBeat);
} }
} }
@ -431,7 +444,14 @@ namespace HeavenStudio
{ {
if (songPositionInBeatsAsDouble >= Math.Ceiling(startBeat) + _metronomeTally) if (songPositionInBeatsAsDouble >= Math.Ceiling(startBeat) + _metronomeTally)
{ {
if (metronome) metronomeSound = Util.SoundByte.PlayOneShot("metronome", Math.Ceiling(startBeat) + _metronomeTally); // if (metronome) metronomeSound = Util.SoundByte.PlayOneShot("metronome", Math.Ceiling(startBeat) + _metronomeTally);
if (metronome)
{
metronomeSound = Util.MultiSound.Play(new List<Util.MultiSound.Sound> {
new Util.MultiSound.Sound("metronome", Math.Ceiling(startBeat) + _metronomeTally),
new Util.MultiSound.Sound("metronome", Math.Ceiling(startBeat) + _metronomeTally + 0.5, 1.5f, 0.5f)
}, false, true);
}
_metronomeTally++; _metronomeTally++;
} }
} }
@ -439,7 +459,7 @@ namespace HeavenStudio
{ {
if (metronomeSound != null) if (metronomeSound != null)
{ {
metronomeSound.Stop(); // metronomeSound.StopAll();
metronomeSound = null; metronomeSound = null;
} }
} }
@ -460,9 +480,9 @@ namespace HeavenStudio
return result; return result;
} }
public float GetLoopPositionFromBeat(float beatOffset, float length, bool beatClamp = true) public float GetLoopPositionFromBeat(float beatOffset, float length, bool beatClamp = true, bool ignoreSwing = true)
{ {
float beat = songPositionInBeats; float beat = ignoreSwing ? unswungSongPositionInBeats : songPositionInBeats;
if (beatClamp) if (beatClamp)
{ {
beat = Mathf.Max(beat, 0); beat = Mathf.Max(beat, 0);
@ -470,9 +490,9 @@ namespace HeavenStudio
return Mathf.Repeat((beat / length) + beatOffset, 1); return Mathf.Repeat((beat / length) + beatOffset, 1);
} }
public float GetPositionFromBeat(double startBeat, double length, bool beatClamp = true) public float GetPositionFromBeat(double startBeat, double length, bool beatClamp = true, bool ignoreSwing = true)
{ {
float beat = songPositionInBeats; float beat = ignoreSwing ? unswungSongPositionInBeats : songPositionInBeats;
if (beatClamp) if (beatClamp)
{ {
beat = Mathf.Max(beat, 0); beat = Mathf.Max(beat, 0);
@ -493,20 +513,11 @@ namespace HeavenStudio
var chart = gameManager.Beatmap; var chart = gameManager.Beatmap;
if (chart.TempoChanges.Count == 0) if (chart.TempoChanges.Count == 0)
return 120f; return 120f;
float bpm = chart.TempoChanges[0]["tempo"];
swingRatio = chart.TempoChanges[0]["swing"] + 0.5f;
foreach (RiqEntity t in chart.TempoChanges) RiqEntity tempoChange = chart.TempoChanges.FindLast(t => t.beat <= beat);
{ tempoChange ??= chart.TempoChanges[0];
if (t.beat > beat) swingRatio = tempoChange["swing"] + 0.5f;
{ return tempoChange["tempo"];
break;
}
bpm = t["tempo"];
swingRatio = t["swing"] + 0.5f;
}
return bpm;
} }
public float GetBpmAtBeat(double beat) public float GetBpmAtBeat(double beat)
@ -521,25 +532,53 @@ namespace HeavenStudio
return swingRatio; return swingRatio;
} }
public double GetSwungBeat(double beat)
{
return Math.Floor(beat) + GetSwingOffset(beat, GetSwingRatioAtBeat(beat));
}
public double GetSwungBeat(double beat, float ratio) public double GetSwungBeat(double beat, float ratio)
{ {
return beat + GetSwingOffset(beat, ratio); return Math.Floor(beat) + GetSwingOffset(beat, ratio);
} }
public double GetSwingOffset(double beatFrac, float ratio) public double GetSwingOffset(double beatFrac, float ratio)
{ {
beatFrac %= 1; beatFrac %= 1;
if (beatFrac <= 0.5) if (beatFrac <= ratio)
{ {
return 0.5 / ratio * beatFrac; return 0.5 / ratio * beatFrac;
} }
else else
{ {
return 0.5 + (0.5 / (1f - ratio) * (beatFrac - ratio)); return 0.5 + 0.5 / (1 - ratio) * (beatFrac - ratio);
} }
} }
public double GetSongPosFromBeat(double beat) public double GetUnSwungBeat(double beat)
{
return Math.Floor(beat) + GetUnSwingOffset(beat, GetSwingRatioAtBeat(beat));
}
public double GetUnSwungBeat(double beat, float ratio)
{
return Math.Floor(beat) + GetUnSwingOffset(beat, ratio);
}
public double GetUnSwingOffset(double beatFrac, float ratio)
{
beatFrac %= 1;
if (beatFrac <= ratio)
{
return 2 * ratio * beatFrac;
}
else
{
return 2 * (beatFrac - 0.5f) * (1f - ratio) + ratio;
}
}
public double GetSongPosFromBeat(double beat, bool ignoreSwing = false)
{ {
var chart = gameManager.Beatmap; var chart = gameManager.Beatmap;
float bpm = 120f; float bpm = 120f;
@ -548,6 +587,11 @@ namespace HeavenStudio
double lastTempoChangeBeat = 0f; double lastTempoChangeBeat = 0f;
if (!ignoreSwing)
{
beat = GetUnSwungBeat(beat);
}
foreach (RiqEntity t in chart.TempoChanges) foreach (RiqEntity t in chart.TempoChanges)
{ {
if (t.beat > beat) if (t.beat > beat)

View file

@ -236,7 +236,6 @@ namespace HeavenStudio
public void NewRemix() public void NewRemix()
{ {
Debug.Log("Creating new remix");
AudioLoadDone = false; AudioLoadDone = false;
Beatmap = new("1", "HeavenStudio"); Beatmap = new("1", "HeavenStudio");
Beatmap.data.properties = new(Minigames.propertiesModel); Beatmap.data.properties = new(Minigames.propertiesModel);
@ -447,7 +446,7 @@ namespace HeavenStudio
var inf = GetGameInfo(gameName); var inf = GetGameInfo(gameName);
if (inf != null && inf.usesAssetBundle && inf.AssetsLoaded && !inf.SequencesPreloaded) if (inf != null && inf.usesAssetBundle && inf.AssetsLoaded && !inf.SequencesPreloaded)
{ {
Debug.Log($"Preparing game {gameName}"); // Debug.Log($"Preparing game {gameName}");
PreloadGameSequences(gameName); PreloadGameSequences(gameName);
} }
eventCaller.CallPreEvent(entity); eventCaller.CallPreEvent(entity);
@ -462,32 +461,31 @@ namespace HeavenStudio
{ {
if (BeatmapEntities() < 1) if (BeatmapEntities() < 1)
return; return;
if (!conductor.isPlaying) if (conductor.WaitingForDsp || !conductor.isPlaying)
return; return;
Conductor cond = conductor; double clampedBeat = Math.Max(conductor.songPositionInBeatsAsDouble, 0);
double clampedBeat = Math.Max(cond.songPositionInBeatsAsDouble, 0);
if (currentTempoEvent < Beatmap.TempoChanges.Count && currentTempoEvent >= 0) if (currentTempoEvent < Beatmap.TempoChanges.Count && currentTempoEvent >= 0)
{ {
if (cond.songPositionInBeatsAsDouble >= tempoBeats[currentTempoEvent]) if (conductor.songPositionInBeatsAsDouble >= tempoBeats[currentTempoEvent])
{ {
cond.SetBpm(Beatmap.TempoChanges[currentTempoEvent]["tempo"]); conductor.SetBpm(Beatmap.TempoChanges[currentTempoEvent]["tempo"]);
currentTempoEvent++; currentTempoEvent++;
} }
} }
if (currentVolumeEvent < Beatmap.VolumeChanges.Count && currentVolumeEvent >= 0) if (currentVolumeEvent < Beatmap.VolumeChanges.Count && currentVolumeEvent >= 0)
{ {
if (cond.songPositionInBeatsAsDouble >= volumeBeats[currentVolumeEvent]) if (conductor.songPositionInBeatsAsDouble >= volumeBeats[currentVolumeEvent])
{ {
cond.SetVolume(Beatmap.VolumeChanges[currentVolumeEvent]["volume"]); conductor.SetVolume(Beatmap.VolumeChanges[currentVolumeEvent]["volume"]);
currentVolumeEvent++; currentVolumeEvent++;
} }
} }
if (currentSectionEvent < Beatmap.SectionMarkers.Count && currentSectionEvent >= 0) if (currentSectionEvent < Beatmap.SectionMarkers.Count && currentSectionEvent >= 0)
{ {
if (cond.songPositionInBeatsAsDouble >= sectionBeats[currentSectionEvent]) if (conductor.songPositionInBeatsAsDouble >= sectionBeats[currentSectionEvent])
{ {
RiqEntity marker = Beatmap.SectionMarkers[currentSectionEvent]; RiqEntity marker = Beatmap.SectionMarkers[currentSectionEvent];
if (!string.IsNullOrEmpty(marker["sectionName"])) if (!string.IsNullOrEmpty(marker["sectionName"]))
@ -529,7 +527,7 @@ namespace HeavenStudio
} }
} }
if (cond.songPositionInBeatsAsDouble >= Math.Ceiling(_playStartBeat) + _pulseTally) if (conductor.songPositionInBeatsAsDouble >= Math.Ceiling(_playStartBeat) + _pulseTally)
{ {
if (minigame != null) minigame.OnBeatPulse(Math.Ceiling(_playStartBeat) + _pulseTally); if (minigame != null) minigame.OnBeatPulse(Math.Ceiling(_playStartBeat) + _pulseTally);
onBeatPulse?.Invoke(Math.Ceiling(_playStartBeat) + _pulseTally); onBeatPulse?.Invoke(Math.Ceiling(_playStartBeat) + _pulseTally);
@ -546,7 +544,7 @@ namespace HeavenStudio
List<RiqEntity> entitiesInRange = ListPool<RiqEntity>.Get(); List<RiqEntity> entitiesInRange = ListPool<RiqEntity>.Get();
List<RiqEntity> fxEntities = ListPool<RiqEntity>.Get(); List<RiqEntity> fxEntities = ListPool<RiqEntity>.Get();
// allows for multiple events on the same beat to be executed on the same frame, so no more 1-frame delay // allows for multiple events on the same beat to be executed on the same frame, so no more 1-frame delay
while (currentEvent < eventBeats.Count && clampedBeat >= eventBeats[currentEvent] && conductor.isPlaying) while (currentEvent < eventBeats.Count && clampedBeat >= eventBeats[currentEvent] && this.conductor.isPlaying)
{ {
fxEntities.Clear(); fxEntities.Clear();
entitiesInRange.Clear(); entitiesInRange.Clear();
@ -602,9 +600,9 @@ namespace HeavenStudio
} }
else else
{ {
double currectSectionStart = cond.GetSongPosFromBeat(currentSection.beat); double currectSectionStart = conductor.GetSongPosFromBeat(currentSection.beat);
SectionProgress = (cond.songPosition - currectSectionStart) / (cond.GetSongPosFromBeat(nextSectionBeat) - currectSectionStart); SectionProgress = (conductor.songPosition - currectSectionStart) / (conductor.GetSongPosFromBeat(nextSectionBeat) - currectSectionStart);
} }
} }
@ -672,7 +670,6 @@ namespace HeavenStudio
public void Play(double beat, float delay = 0f) public void Play(double beat, float delay = 0f)
{ {
bool paused = conductor.isPaused; bool paused = conductor.isPaused;
Debug.Log("Playing at " + beat);
_playStartBeat = beat; _playStartBeat = beat;
_pulseTally = 0; _pulseTally = 0;
_latePulseTally = 0; _latePulseTally = 0;
@ -721,7 +718,9 @@ namespace HeavenStudio
conductor.SetBpm(Beatmap.TempoChanges[0]["tempo"]); conductor.SetBpm(Beatmap.TempoChanges[0]["tempo"]);
conductor.SetVolume(Beatmap.VolumeChanges[0]["volume"]); conductor.SetVolume(Beatmap.VolumeChanges[0]["volume"]);
conductor.firstBeatOffset = Beatmap.data.offset; conductor.firstBeatOffset = Beatmap.data.offset;
conductor.PlaySetup(beat);
SetCurrentEventToClosest(beat); SetCurrentEventToClosest(beat);
Debug.Log("Playing at " + beat);
KillAllSounds(); KillAllSounds();
if (delay > 0) if (delay > 0)
@ -729,7 +728,6 @@ namespace HeavenStudio
yield return new WaitForSeconds(delay); yield return new WaitForSeconds(delay);
} }
conductor.PlaySetup(beat);
Minigame miniGame = null; Minigame miniGame = null;
if (minigameObj != null && minigameObj.TryGetComponent<Minigame>(out miniGame)) if (minigameObj != null && minigameObj.TryGetComponent<Minigame>(out miniGame))
{ {
@ -819,6 +817,10 @@ namespace HeavenStudio
GlobalGameManager.LoadScene("Judgement", 0.35f, 0f, DestroyGame); GlobalGameManager.LoadScene("Judgement", 0.35f, 0f, DestroyGame);
CircleCursor.LockCursor(false); CircleCursor.LockCursor(false);
} }
else
{
conductor.SetBeat(beat);
}
Application.backgroundLoadingPriority = ThreadPriority.Normal; Application.backgroundLoadingPriority = ThreadPriority.Normal;
} }
@ -833,6 +835,8 @@ namespace HeavenStudio
SoundByte.PreloadAudioClipAsync("skillStar"); SoundByte.PreloadAudioClipAsync("skillStar");
SoundByte.PreloadAudioClipAsync("perfectMiss"); SoundByte.PreloadAudioClipAsync("perfectMiss");
conductor.SetBeat(beat);
WaitUntil yieldOverlays = new WaitUntil(() => OverlaysManager.OverlaysReady); WaitUntil yieldOverlays = new WaitUntil(() => OverlaysManager.OverlaysReady);
WaitUntil yieldBeatmap = new WaitUntil(() => Beatmap != null && BeatmapEntities() > 0); WaitUntil yieldBeatmap = new WaitUntil(() => Beatmap != null && BeatmapEntities() > 0);
WaitUntil yieldAudio = new WaitUntil(() => AudioLoadDone || (ChartLoadError && !GlobalGameManager.IsShowingDialog)); WaitUntil yieldAudio = new WaitUntil(() => AudioLoadDone || (ChartLoadError && !GlobalGameManager.IsShowingDialog));
@ -845,16 +849,16 @@ namespace HeavenStudio
} }
// wait for overlays to be ready // wait for overlays to be ready
Debug.Log("waiting for overlays"); // Debug.Log("waiting for overlays");
yield return yieldOverlays; yield return yieldOverlays;
// wait for beatmap to be loaded // wait for beatmap to be loaded
Debug.Log("waiting for beatmap"); // Debug.Log("waiting for beatmap");
yield return yieldBeatmap; yield return yieldBeatmap;
//wait for audio clip to be loaded //wait for audio clip to be loaded
Debug.Log("waiting for audio"); // Debug.Log("waiting for audio");
yield return yieldAudio; yield return yieldAudio;
//wait for games to be loaded //wait for games to be loaded
Debug.Log("waiting for minigames"); // Debug.Log("waiting for minigames");
if (yieldGame != null) if (yieldGame != null)
yield return yieldGame; yield return yieldGame;
@ -874,7 +878,7 @@ namespace HeavenStudio
public void KillAllSounds() public void KillAllSounds()
{ {
Debug.Log("Killing all sounds"); // Debug.Log("Killing all sounds");
SoundObjects.Clear(); SoundObjects.Clear();
SoundByte.KillOneShots(); SoundByte.KillOneShots();
} }
@ -898,9 +902,10 @@ namespace HeavenStudio
allGameSwitches = EventCaller.GetAllInGameManagerList("gameManager", new string[] { "switchGame" }); allGameSwitches = EventCaller.GetAllInGameManagerList("gameManager", new string[] { "switchGame" });
preSequenceBeats = new List<double>(); preSequenceBeats = new List<double>();
string[] seekEntityDatamodel;
foreach (RiqEntity entity in Beatmap.Entities) foreach (RiqEntity entity in Beatmap.Entities)
{ {
string[] seekEntityDatamodel = entity.datamodel.Split('/'); seekEntityDatamodel = entity.datamodel.Split('/');
double seekTime = eventCaller.GetGameAction(seekEntityDatamodel[0], seekEntityDatamodel[1]).preFunctionLength; double seekTime = eventCaller.GetGameAction(seekEntityDatamodel[0], seekEntityDatamodel[1]).preFunctionLength;
preSequenceBeats.Add(entity.beat - seekTime); preSequenceBeats.Add(entity.beat - seekTime);
} }
@ -1168,7 +1173,7 @@ namespace HeavenStudio
{ {
if (!(inf.AssetsLoaded || inf.AlreadyLoading)) if (!(inf.AssetsLoaded || inf.AlreadyLoading))
{ {
Debug.Log($"ASYNC loading assetbundles for game {game}"); // Debug.Log($"ASYNC loading assetbundles for game {game}");
inf.LoadAssetsAsync().Forget(); inf.LoadAssetsAsync().Forget();
} }
yield return new WaitUntil(() => inf.AssetsLoaded); yield return new WaitUntil(() => inf.AssetsLoaded);

View file

@ -390,7 +390,7 @@ namespace HeavenStudio.Games
//idol jumping physics //idol jumping physics
float jumpPos = conductor.GetPositionFromBeat(idolJumpStartTime, 1f); float jumpPos = conductor.GetPositionFromBeat(idolJumpStartTime, 1f);
float IDOL_SHADOW_SCALE = 1.18f; float IDOL_SHADOW_SCALE = 1.18f;
if (conductor.songPositionInBeatsAsDouble >= idolJumpStartTime && conductor.songPositionInBeatsAsDouble < idolJumpStartTime + 1f) if (conductor.unswungSongPositionInBeatsAsDouble >= idolJumpStartTime && conductor.unswungSongPositionInBeatsAsDouble < idolJumpStartTime + 1f)
{ {
hasJumped = true; hasJumped = true;
float yMul = jumpPos * 2f - 1f; float yMul = jumpPos * 2f - 1f;
@ -580,7 +580,7 @@ namespace HeavenStudio.Games
{ {
DisableBop(beat, length); DisableBop(beat, length);
DisableResponse(beat, length); DisableResponse(beat, length);
idolJumpStartTime = beat; idolJumpStartTime = conductor.GetUnSwungBeat(beat);
//play anim //play anim
BeatAction.New(instance, new List<BeatAction.Action>() BeatAction.New(instance, new List<BeatAction.Action>()

View file

@ -69,7 +69,7 @@ namespace HeavenStudio.Games.Scripts_FanClub
//idol jumping physics //idol jumping physics
float jumpPos = cond.GetPositionFromBeat(startJumpTime, 1f); float jumpPos = cond.GetPositionFromBeat(startJumpTime, 1f);
float IDOL_SHADOW_SCALE = 1.18f; float IDOL_SHADOW_SCALE = 1.18f;
if (cond.songPositionInBeatsAsDouble >= startJumpTime && cond.songPositionInBeatsAsDouble < startJumpTime + 1f) if (cond.unswungSongPositionInBeatsAsDouble >= startJumpTime && cond.unswungSongPositionInBeatsAsDouble < startJumpTime + 1f)
{ {
hasJumped = true; hasJumped = true;
float yMul = jumpPos * 2f - 1f; float yMul = jumpPos * 2f - 1f;
@ -77,7 +77,7 @@ namespace HeavenStudio.Games.Scripts_FanClub
rootTransform.transform.localPosition = new Vector3(startPostion + stepDistance * AnimCount, rootYPos + (2f * yWeight + 0.25f)); rootTransform.transform.localPosition = new Vector3(startPostion + stepDistance * AnimCount, rootYPos + (2f * yWeight + 0.25f));
shadow.transform.localScale = new Vector3((1f-yWeight*0.8f) * IDOL_SHADOW_SCALE, (1f-yWeight*0.8f) * IDOL_SHADOW_SCALE, 1f); shadow.transform.localScale = new Vector3((1f-yWeight*0.8f) * IDOL_SHADOW_SCALE, (1f-yWeight*0.8f) * IDOL_SHADOW_SCALE, 1f);
anim.DoScaledAnimation("Jump", startJumpTime, 1f); anim.DoScaledAnimation("Jump", startJumpTime, 1f, ignoreSwing: true);
} }
else else
{ {
@ -160,12 +160,11 @@ namespace HeavenStudio.Games.Scripts_FanClub
{ {
if (startStepBeat != double.MaxValue) return; if (startStepBeat != double.MaxValue) return;
if (!gameObject.activeInHierarchy) return; if (!gameObject.activeInHierarchy) return;
startJumpTime = beat; startJumpTime = Conductor.instance.GetUnSwungBeat(beat);
//play anim //play anim
BeatAction.New(this, new List<BeatAction.Action>() BeatAction.New(this, new List<BeatAction.Action>()
{ {
// new BeatAction.Action(beat, delegate { anim.Play("Jump", -1, 0); }),
new BeatAction.Action(beat + 1f, delegate { anim.Play("Land", -1, 0); }), new BeatAction.Action(beat + 1f, delegate { anim.Play("Land", -1, 0); }),
}); });
} }

View file

@ -116,7 +116,7 @@ namespace HeavenStudio.Games.Scripts_FanClub
} }
if (PlayerInput.GetIsAction(FanClub.InputAction_BasicPressing)) if (PlayerInput.GetIsAction(FanClub.InputAction_BasicPressing))
{ {
if (clappingStartTime != double.MinValue && cond.songPositionInBeatsAsDouble > clappingStartTime + 2f && !stopCharge) if (clappingStartTime != double.MinValue && cond.unswungSongPositionInBeatsAsDouble > clappingStartTime + 2f && !stopCharge)
{ {
animator.speed = 1f; animator.speed = 1f;
animator.Play("FanClapCharge", -1, 0); animator.Play("FanClapCharge", -1, 0);
@ -131,7 +131,7 @@ namespace HeavenStudio.Games.Scripts_FanClub
nonTouchDelay = 0f; nonTouchDelay = 0f;
stopCharge = true; stopCharge = true;
} }
if (clappingStartTime != double.MinValue && cond.songPositionInBeatsAsDouble > clappingStartTime + nonTouchDelay && stopCharge if (clappingStartTime != double.MinValue && cond.unswungSongPositionInBeatsAsDouble > clappingStartTime + nonTouchDelay && stopCharge
&& !FanClub.instance.IsExpectingInputNow(FanClub.InputAction_FlickRelease.inputLockCategory)) && !FanClub.instance.IsExpectingInputNow(FanClub.InputAction_FlickRelease.inputLockCategory))
{ {
if (FanClub.instance.JudgementPaused) if (FanClub.instance.JudgementPaused)
@ -163,14 +163,14 @@ namespace HeavenStudio.Games.Scripts_FanClub
} }
float jumpPos = cond.GetPositionFromBeat(jumpStartTime, 1f); float jumpPos = cond.GetPositionFromBeat(jumpStartTime, 1f);
if (cond.songPositionInBeatsAsDouble >= jumpStartTime && cond.songPositionInBeatsAsDouble < jumpStartTime + 1f) if (cond.unswungSongPositionInBeatsAsDouble >= jumpStartTime && cond.unswungSongPositionInBeatsAsDouble < jumpStartTime + 1f)
{ {
hasJumped = true; hasJumped = true;
float yMul = jumpPos * 2f - 1f; float yMul = jumpPos * 2f - 1f;
float yWeight = -(yMul*yMul) + 1f; float yWeight = -(yMul*yMul) + 1f;
motionRoot.transform.localPosition = new Vector3(0, 3f * yWeight); motionRoot.transform.localPosition = new Vector3(0, 3f * yWeight);
shadow.transform.localScale = new Vector3((1f-yWeight*0.8f) * 1.4f, (1f-yWeight*0.8f) * 1.4f, 1f); shadow.transform.localScale = new Vector3((1f-yWeight*0.8f) * 1.4f, (1f-yWeight*0.8f) * 1.4f, 1f);
animator.DoScaledAnimation("FanJump", jumpStartTime); animator.DoScaledAnimation("FanJump", jumpStartTime, ignoreSwing: true);
} }
else else
{ {
@ -205,12 +205,12 @@ namespace HeavenStudio.Games.Scripts_FanClub
var cond = Conductor.instance; var cond = Conductor.instance;
hasJumped = false; hasJumped = false;
stopBeat = true; stopBeat = true;
jumpStartTime = -99f; jumpStartTime = double.MinValue;
animator.speed = 1f; animator.speed = 1f;
animator.Play("FanClap", -1, 0); animator.Play("FanClap", -1, 0);
SoundByte.PlayOneShotGame("fanClub/play_clap"); SoundByte.PlayOneShotGame("fanClub/play_clap");
SoundByte.PlayOneShotGame("fanClub/crap_impact"); SoundByte.PlayOneShotGame("fanClub/crap_impact");
clappingStartTime = cond.songPositionInBeatsAsDouble; clappingStartTime = cond.unswungSongPositionInBeatsAsDouble;
if (doCharge) if (doCharge)
BeatAction.New(this, new List<BeatAction.Action>() BeatAction.New(this, new List<BeatAction.Action>()
@ -247,7 +247,7 @@ namespace HeavenStudio.Games.Scripts_FanClub
var cond = Conductor.instance; var cond = Conductor.instance;
animator.Play("FanJump", -1, 0); animator.Play("FanJump", -1, 0);
SoundByte.PlayOneShotGame("fanClub/play_jump"); SoundByte.PlayOneShotGame("fanClub/play_jump");
jumpStartTime = cond.songPositionInBeatsAsDouble; jumpStartTime = cond.unswungSongPositionInBeatsAsDouble;
clappingStartTime = double.MinValue; clappingStartTime = double.MinValue;
stopCharge = false; stopCharge = false;
} }
@ -255,7 +255,7 @@ namespace HeavenStudio.Games.Scripts_FanClub
public bool IsJumping() public bool IsJumping()
{ {
var cond = Conductor.instance; var cond = Conductor.instance;
return (cond.songPositionInBeatsAsDouble >= jumpStartTime && cond.songPositionInBeatsAsDouble < jumpStartTime + 1f); return (cond.unswungSongPositionInBeatsAsDouble >= jumpStartTime && cond.unswungSongPositionInBeatsAsDouble < jumpStartTime + 1f);
} }
public void Bop() public void Bop()

View file

@ -7,6 +7,7 @@ using HeavenStudio.Util;
using HeavenStudio.InputSystem; using HeavenStudio.InputSystem;
using Jukebox; using Jukebox;
using System.Linq; using System.Linq;
using BurstLinq;
namespace HeavenStudio.Games.Loaders namespace HeavenStudio.Games.Loaders
{ {

View file

@ -38,7 +38,7 @@ namespace HeavenStudio.Games.Scripts_KarateMan
public bool KickBarrelContent = false; public bool KickBarrelContent = false;
public bool ShouldGlow = false; public bool ShouldGlow = false;
public int OnHitExpression = (int) KarateMan.KarateManFaces.Normal; public int OnHitExpression = (int)KarateMan.KarateManFaces.Normal;
public int comboId = -1; public int comboId = -1;
static int _lastCombo = -1; static int _lastCombo = -1;
@ -266,8 +266,6 @@ namespace HeavenStudio.Games.Scripts_KarateMan
transform.rotation = Quaternion.Euler(0, 0, transform.rotation.eulerAngles.z + (-360f * Time.deltaTime) + UnityEngine.Random.Range(0f, 360f)); transform.rotation = Quaternion.Euler(0, 0, transform.rotation.eulerAngles.z + (-360f * Time.deltaTime) + UnityEngine.Random.Range(0f, 360f));
ShadowInstance = Instantiate(Shadow, KarateMan.instance.ItemHolder); ShadowInstance = Instantiate(Shadow, KarateMan.instance.ItemHolder);
shadowRenderer = ShadowInstance.GetComponent<SpriteRenderer>(); shadowRenderer = ShadowInstance.GetComponent<SpriteRenderer>();
shadowRenderer.color = KarateMan.instance.Joe.Shadows[0].color; shadowRenderer.color = KarateMan.instance.Joe.Shadows[0].color;
@ -585,9 +583,12 @@ namespace HeavenStudio.Games.Scripts_KarateMan
p.Play(); p.Play();
break; break;
case ItemType.KickBarrel: case ItemType.KickBarrel:
if (KickBarrelContent) { if (KickBarrelContent)
{
game.CreateItemInstance(startBeat + 1f, "Item03", OnHitExpression, ItemType.KickBall); game.CreateItemInstance(startBeat + 1f, "Item03", OnHitExpression, ItemType.KickBall);
} else { }
else
{
if (ShouldGlow) game.Joe.ApplyBombGlow(); if (ShouldGlow) game.Joe.ApplyBombGlow();
game.CreateItemInstance(startBeat + 1f, "Item04", OnHitExpression, ItemType.KickBomb); game.CreateItemInstance(startBeat + 1f, "Item04", OnHitExpression, ItemType.KickBomb);
} }
@ -629,7 +630,7 @@ namespace HeavenStudio.Games.Scripts_KarateMan
break; break;
} }
startBeat = Conductor.instance.songPositionInBeatsAsDouble; startBeat = Conductor.instance.unswungSongPositionInBeatsAsDouble;
status = FlyStatus.Hit; status = FlyStatus.Hit;
} }
@ -765,7 +766,7 @@ namespace HeavenStudio.Games.Scripts_KarateMan
if (state <= -1f || state >= 1f) if (state <= -1f || state >= 1f)
{ {
bool straight = joe.Punch(ItemPunchHand(), false, ItemPunchHand() == 2); bool straight = joe.Punch(ItemPunchHand(), false, ItemPunchHand() == 2);
startBeat = Conductor.instance.songPositionInBeatsAsDouble; startBeat = Conductor.instance.unswungSongPositionInBeatsAsDouble;
CurrentCurve = ItemCurves[6]; CurrentCurve = ItemCurves[6];
curveTargetBeat = 1f; curveTargetBeat = 1f;
SoundByte.PlayOneShot("miss"); SoundByte.PlayOneShot("miss");
@ -788,7 +789,7 @@ namespace HeavenStudio.Games.Scripts_KarateMan
if (ItemNeedNori() && KarateMan.instance.NoriPerformance < 0.6f) if (ItemNeedNori() && KarateMan.instance.NoriPerformance < 0.6f)
{ {
CreateHitMark(false); CreateHitMark(false);
startBeat = Conductor.instance.songPositionInBeatsAsDouble; startBeat = Conductor.instance.unswungSongPositionInBeatsAsDouble;
status = FlyStatus.HitWeak; status = FlyStatus.HitWeak;
SoundByte.PlayOneShotGame("karateman/hitNoNori", forcePlay: true); SoundByte.PlayOneShotGame("karateman/hitNoNori", forcePlay: true);
joe.Punch(3); joe.Punch(3);
@ -815,7 +816,7 @@ namespace HeavenStudio.Games.Scripts_KarateMan
joe.ForceFailCombo(Conductor.instance.songPositionInBeatsAsDouble); joe.ForceFailCombo(Conductor.instance.songPositionInBeatsAsDouble);
if (state <= -1f || state >= 1f) if (state <= -1f || state >= 1f)
{ {
startBeat = Conductor.instance.songPositionInBeatsAsDouble; startBeat = Conductor.instance.unswungSongPositionInBeatsAsDouble;
CurrentCurve = ItemCurves[6]; CurrentCurve = ItemCurves[6];
curveTargetBeat = 1f; curveTargetBeat = 1f;
SoundByte.PlayOneShot("miss"); SoundByte.PlayOneShot("miss");
@ -885,7 +886,7 @@ namespace HeavenStudio.Games.Scripts_KarateMan
joe.SetShouldComboId(comboId); joe.SetShouldComboId(comboId);
if (state <= -1f || state >= 1f) if (state <= -1f || state >= 1f)
{ {
startBeat = Conductor.instance.songPositionInBeatsAsDouble; startBeat = Conductor.instance.unswungSongPositionInBeatsAsDouble;
CurrentCurve = ItemCurves[6]; CurrentCurve = ItemCurves[6];
curveTargetBeat = 1f; curveTargetBeat = 1f;
SoundByte.PlayOneShot("miss"); SoundByte.PlayOneShot("miss");
@ -932,7 +933,7 @@ namespace HeavenStudio.Games.Scripts_KarateMan
bool straight = joe.Punch(ItemPunchHand()); bool straight = joe.Punch(ItemPunchHand());
if (state <= -1f || state >= 1f) if (state <= -1f || state >= 1f)
{ {
startBeat = Conductor.instance.songPositionInBeatsAsDouble; startBeat = Conductor.instance.unswungSongPositionInBeatsAsDouble;
CurrentCurve = ItemCurves[6]; CurrentCurve = ItemCurves[6];
curveTargetBeat = 1f; curveTargetBeat = 1f;
SoundByte.PlayOneShot("miss"); SoundByte.PlayOneShot("miss");
@ -962,7 +963,7 @@ namespace HeavenStudio.Games.Scripts_KarateMan
joe.ComboSequence(3); joe.ComboSequence(3);
if (state <= -1f || state >= 1f) if (state <= -1f || state >= 1f)
{ {
startBeat = Conductor.instance.songPositionInBeatsAsDouble; startBeat = Conductor.instance.unswungSongPositionInBeatsAsDouble;
CurrentCurve = ItemCurves[5]; CurrentCurve = ItemCurves[5];
curveTargetBeat = 1f; curveTargetBeat = 1f;
SoundByte.PlayOneShot("miss"); SoundByte.PlayOneShot("miss");
@ -1052,7 +1053,7 @@ namespace HeavenStudio.Games.Scripts_KarateMan
joe.Punch(ItemPunchHand()); joe.Punch(ItemPunchHand());
if (state <= -1f || state >= 1f) if (state <= -1f || state >= 1f)
{ {
startBeat = Conductor.instance.songPositionInBeatsAsDouble; startBeat = Conductor.instance.unswungSongPositionInBeatsAsDouble;
CurrentCurve = ItemCurves[6]; CurrentCurve = ItemCurves[6];
curveTargetBeat = 1f; curveTargetBeat = 1f;
SoundByte.PlayOneShot("miss"); SoundByte.PlayOneShot("miss");
@ -1114,7 +1115,7 @@ namespace HeavenStudio.Games.Scripts_KarateMan
joe.Kick(Conductor.instance.songPositionInBeatsAsDouble); joe.Kick(Conductor.instance.songPositionInBeatsAsDouble);
if (state <= -1f || state >= 1f) if (state <= -1f || state >= 1f)
{ {
startBeat = Conductor.instance.songPositionInBeatsAsDouble; startBeat = Conductor.instance.unswungSongPositionInBeatsAsDouble;
CurrentCurve = ItemCurves[8]; CurrentCurve = ItemCurves[8];
curveTargetBeat = 1f; curveTargetBeat = 1f;
SoundByte.PlayOneShot("miss"); SoundByte.PlayOneShot("miss");
@ -1140,7 +1141,7 @@ namespace HeavenStudio.Games.Scripts_KarateMan
ItemHitEffect(); ItemHitEffect();
status = FlyStatus.Hit; status = FlyStatus.Hit;
CurrentCurve = ItemCurves[7]; CurrentCurve = ItemCurves[7];
startBeat = Conductor.instance.songPositionInBeatsAsDouble; startBeat = Conductor.instance.unswungSongPositionInBeatsAsDouble;
curveTargetBeat = 3f; curveTargetBeat = 3f;
KarateMan.instance.Nori.DoHit(); KarateMan.instance.Nori.DoHit();
} }

View file

@ -123,7 +123,7 @@ namespace HeavenStudio.Games.Scripts_PajamaParty
public void Jump(double beat, int alt = 1) public void Jump(double beat, int alt = 1)
{ {
startJumpTime = beat; startJumpTime = Conductor.instance.GetUnSwungBeat(beat);
jumpAlt = 0; jumpAlt = 0;
if (alt > 1) if (alt > 1)
{ {
@ -140,7 +140,7 @@ namespace HeavenStudio.Games.Scripts_PajamaParty
public void Throw(double beat, bool highCheck) public void Throw(double beat, bool highCheck)
{ {
anim.DoUnscaledAnimation("MonkeyThrow" + animSuffix); anim.DoUnscaledAnimation("MonkeyThrow" + animSuffix);
startThrowTime = beat; startThrowTime = Conductor.instance.GetUnSwungBeat(beat);
Projectile.SetActive(true); Projectile.SetActive(true);
if (highCheck) if (highCheck)

View file

@ -182,7 +182,7 @@ namespace HeavenStudio.Games.Scripts_PajamaParty
{ {
throwType = false; throwType = false;
throwLength = 0.5; throwLength = 0.5;
Projectile.GetComponent<Animator>().DoScaledAnimation("ThrowOut", startThrowTime, throwLength); Projectile.GetComponent<Animator>().DoScaledAnimation("ThrowOut", Conductor.instance.GetUnSwungBeat(startThrowTime), throwLength);
Projectile.transform.rotation = Quaternion.Euler(0, 0, 360f * UnityEngine.Random.Range(0f, 1f)); Projectile.transform.rotation = Quaternion.Euler(0, 0, 360f * UnityEngine.Random.Range(0f, 1f));
} }
else else
@ -310,12 +310,12 @@ namespace HeavenStudio.Games.Scripts_PajamaParty
if (state <= -1f || state >= 1f) if (state <= -1f || state >= 1f)
{ {
SoundByte.PlayOneShot("miss"); SoundByte.PlayOneShot("miss");
PlayerJump(cond.songPositionInBeatsAsDouble, false, true); PlayerJump(cond.unswungSongPositionInBeatsAsDouble, false, true);
} }
else else
{ {
SoundByte.PlayOneShotGame("pajamaParty/jumpJust"); SoundByte.PlayOneShotGame("pajamaParty/jumpJust");
PlayerJump(cond.songPositionInBeatsAsDouble, false, false); PlayerJump(cond.unswungSongPositionInBeatsAsDouble, false, false);
} }
caller.CanHit(false); caller.CanHit(false);
} }
@ -328,7 +328,7 @@ namespace HeavenStudio.Games.Scripts_PajamaParty
if (canJump) if (canJump)
{ {
var cond = Conductor.instance; var cond = Conductor.instance;
PlayerThrough(cond.songPositionInBeatsAsDouble); PlayerThrough(cond.unswungSongPositionInBeatsAsDouble);
} }
} }
////// //////
@ -359,12 +359,12 @@ namespace HeavenStudio.Games.Scripts_PajamaParty
{ {
SoundByte.PlayOneShot("miss"); SoundByte.PlayOneShot("miss");
throwNg = true; throwNg = true;
EndCharge(cond.songPositionInBeatsAsDouble, true, throwNg); EndCharge(cond.unswungSongPositionInBeatsAsDouble, true, throwNg);
} }
else else
{ {
SoundByte.PlayOneShotGame("pajamaParty/throw5"); SoundByte.PlayOneShotGame("pajamaParty/throw5");
EndCharge(cond.songPositionInBeatsAsDouble, true, throwNg); EndCharge(cond.unswungSongPositionInBeatsAsDouble, true, throwNg);
} }
caller.CanHit(false); caller.CanHit(false);
} }
@ -374,7 +374,7 @@ namespace HeavenStudio.Games.Scripts_PajamaParty
if (canCharge) if (canCharge)
{ {
var cond = Conductor.instance; var cond = Conductor.instance;
PlayerThrough(cond.songPositionInBeatsAsDouble); PlayerThrough(cond.unswungSongPositionInBeatsAsDouble);
} }
} }
// //

View file

@ -43,7 +43,7 @@ namespace HeavenStudio.Games.Scripts_RhythmTweezers
var hairDirection = new Vector3(tst.x + 0.173f, tst.y) - holder.transform.position; var hairDirection = new Vector3(tst.x + 0.173f, tst.y) - holder.transform.position;
holder.transform.rotation = Quaternion.FromToRotation(Vector3.down, hairDirection); holder.transform.rotation = Quaternion.FromToRotation(Vector3.down, hairDirection);
float normalizedBeat = Conductor.instance.GetPositionFromBeat(inputBeat, 0.5f); float normalizedBeat = Conductor.instance.GetPositionFromBeat(inputBeat, 0.5f, ignoreSwing: false);
anim.Play("LoopPull", 0, normalizedBeat); anim.Play("LoopPull", 0, normalizedBeat);
tweezers.anim.Play("Tweezers_LongPluck", 0, normalizedBeat); tweezers.anim.Play("Tweezers_LongPluck", 0, normalizedBeat);
if (!game.IsExpectingInputNow(RhythmTweezers.InputAction_Release) && PlayerInput.GetIsAction(RhythmTweezers.InputAction_Release) && normalizedBeat < 1f) if (!game.IsExpectingInputNow(RhythmTweezers.InputAction_Release) && PlayerInput.GetIsAction(RhythmTweezers.InputAction_Release) && normalizedBeat < 1f)
@ -73,7 +73,7 @@ namespace HeavenStudio.Games.Scripts_RhythmTweezers
public void EndEarly() public void EndEarly()
{ {
var normalized = Conductor.instance.GetPositionFromBeat(inputBeat, 0.5f); var normalized = Conductor.instance.GetPositionFromBeat(inputBeat, 0.5f, ignoreSwing: false);
anim.Play("LoopPullReverse", 0, normalized); anim.Play("LoopPullReverse", 0, normalized);
tweezers.anim.Play("Tweezers_Idle", 0, 0); tweezers.anim.Play("Tweezers_Idle", 0, 0);

View file

@ -293,7 +293,7 @@ namespace HeavenStudio.Games
spawnedHairs.Add(hair); spawnedHairs.Add(hair);
hair.gameObject.SetActive(true); hair.gameObject.SetActive(true);
hair.GetComponent<Animator>().Play("SmallAppear", 0, 1); hair.GetComponent<Animator>().Play("SmallAppear", 0, 1);
float rot = -58f + 116 * crHandlerInstance.GetIntervalProgressFromBeat(beat, 1); float rot = -58f + 116 * crHandlerInstance.GetIntervalProgressFromBeat(conductor.GetUnSwungBeat(beat), 1);
hair.transform.eulerAngles = new Vector3(0, 0, rot); hair.transform.eulerAngles = new Vector3(0, 0, rot);
hair.createBeat = beat; hair.createBeat = beat;
} }
@ -306,7 +306,7 @@ namespace HeavenStudio.Games
spawnedLongs.Add(hair); spawnedLongs.Add(hair);
hair.gameObject.SetActive(true); hair.gameObject.SetActive(true);
hair.GetComponent<Animator>().Play("LongAppear", 0, 1); hair.GetComponent<Animator>().Play("LongAppear", 0, 1);
float rot = -58f + 116 * crHandlerInstance.GetIntervalProgressFromBeat(beat, 1); float rot = -58f + 116 * crHandlerInstance.GetIntervalProgressFromBeat(conductor.GetUnSwungBeat(beat), 1);
hair.transform.eulerAngles = new Vector3(0, 0, rot); hair.transform.eulerAngles = new Vector3(0, 0, rot);
hair.createBeat = beat; hair.createBeat = beat;
} }
@ -333,7 +333,7 @@ namespace HeavenStudio.Games
}) })
}); });
float rot = -58f + 116 * crHandlerInstance.GetIntervalProgressFromBeat(beat, 1); float rot = -58f + 116 * crHandlerInstance.GetIntervalProgressFromBeat(conductor.GetUnSwungBeat(beat), 1);
hair.transform.eulerAngles = new Vector3(0, 0, rot); hair.transform.eulerAngles = new Vector3(0, 0, rot);
hair.createBeat = beat; hair.createBeat = beat;
} }
@ -358,7 +358,7 @@ namespace HeavenStudio.Games
}) })
}); });
float rot = -58f + 116 * crHandlerInstance.GetIntervalProgressFromBeat(beat, 1); float rot = -58f + 116 * crHandlerInstance.GetIntervalProgressFromBeat(conductor.GetUnSwungBeat(beat), 1);
hair.transform.eulerAngles = new Vector3(0, 0, rot); hair.transform.eulerAngles = new Vector3(0, 0, rot);
hair.createBeat = beat; hair.createBeat = beat;
} }

View file

@ -14,6 +14,8 @@ public class TempoDialog : Dialog
[SerializeField] Button deleteButton; [SerializeField] Button deleteButton;
[SerializeField] TMP_InputField tempoInput; [SerializeField] TMP_InputField tempoInput;
[SerializeField] TMP_InputField swingInput;
[SerializeField] Slider swingSlider;
public void SwitchTempoDialog() public void SwitchTempoDialog()
{ {
@ -28,6 +30,9 @@ public class TempoDialog : Dialog
Editor.instance.inAuthorativeMenu = true; Editor.instance.inAuthorativeMenu = true;
ResetAllDialogs(); ResetAllDialogs();
dialog.SetActive(true); dialog.SetActive(true);
swingSlider.maxValue = 0.25f;
swingSlider.minValue = 0;
} }
} }
@ -45,6 +50,8 @@ public class TempoDialog : Dialog
deleteButton.gameObject.SetActive(!tempoObj.first); deleteButton.gameObject.SetActive(!tempoObj.first);
tempoInput.text = tempoObj.chartEntity["tempo"].ToString("F"); tempoInput.text = tempoObj.chartEntity["tempo"].ToString("F");
swingInput.text = (tempoObj.chartEntity["swing"] * 400).ToString("F");
swingSlider.value = tempoObj.chartEntity["swing"];
} }
public void DeleteTempo() public void DeleteTempo()
@ -86,4 +93,25 @@ public class TempoDialog : Dialog
tempoInput.text = tempoObj.chartEntity["tempo"].ToString("F"); 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"];
}
}
} }

View file

@ -62,6 +62,12 @@ namespace HeavenStudio.Editor.Track
SetX(chartEntity); SetX(chartEntity);
} }
public void SetSwing(float swing)
{
chartEntity["swing"] = Mathf.Clamp(swing, 0, 0.5f);
UpdateTempo();
}
public override void Init() public override void Init()
{ {
UpdateTempo(); UpdateTempo();

View file

@ -476,7 +476,7 @@ namespace HeavenStudio.Editor.Track
if (Conductor.instance.metronome) if (Conductor.instance.metronome)
{ {
var startBeat = Mathf.FloorToInt(Conductor.instance.songPositionInBeats - 0.5f); 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); var loop = (startBeat % 2 == 0) ? Mathf.SmoothStep(-1.1f, 1f, nm) : Mathf.SmoothStep(1f, -1f, nm);
rot = loop * 45f; rot = loop * 45f;
@ -674,16 +674,14 @@ namespace HeavenStudio.Editor.Track
public void Play(bool fromStart, float time) public void Play(bool fromStart, float time)
{ {
// if (fromStart) Stop(); GameManager.instance.SafePlay(time, 0, false);
if (!Conductor.instance.isPaused) if (!Conductor.instance.isPaused)
{ {
TimelineSongPosLine = Instantiate(TimelineSongPosLineRef, TimelineSongPosLineRef.parent).GetComponent<RectTransform>(); TimelineSongPosLine = Instantiate(TimelineSongPosLineRef, TimelineSongPosLineRef.parent).GetComponent<RectTransform>();
TimelineSongPosLine.gameObject.SetActive(true); 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); SetTimeButtonColors(false, true, true);
} }

View file

@ -34,10 +34,10 @@ namespace HeavenStudio.Util
/// <param name="length">duration of animation (progress 1.0)</param> /// <param name="length">duration of animation (progress 1.0)</param>
/// <param name="timeScale">multiplier for animation progress (smaller values make animation slower)</param> /// <param name="timeScale">multiplier for animation progress (smaller values make animation slower)</param>
/// <param name="animLayer">animator layer to play animation on</param> /// <param name="animLayer">animator layer to play animation on</param>
public static void DoScaledAnimation(this Animator anim, string animName, double startTime, double length = 1, float timeScale = 1f, int animLayer = -1, bool clamp = false) public static void DoScaledAnimation(this Animator anim, string animName, double startTime, double length = 1, float timeScale = 1f, int animLayer = -1, bool clamp = false, bool ignoreSwing = true)
{ {
if (anim == null) return; if (anim == null) return;
float pos = Conductor.instance.GetPositionFromBeat(startTime, length) * timeScale; float pos = Conductor.instance.GetPositionFromBeat(startTime, length, ignoreSwing: ignoreSwing) * timeScale;
if (clamp) pos = Mathf.Clamp01(pos); if (clamp) pos = Mathf.Clamp01(pos);
anim.Play(animName, animLayer, pos); anim.Play(animName, animLayer, pos);
anim.speed = 1f; //not 0 so these can still play their script events anim.speed = 1f; //not 0 so these can still play their script events

View file

@ -1,7 +1,6 @@
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using BurstLinq;
using UnityEngine; using UnityEngine;
using Cysharp.Threading.Tasks; using Cysharp.Threading.Tasks;
@ -108,12 +107,16 @@ namespace HeavenStudio.Util
Destroy(gameObject); Destroy(gameObject);
} }
public void StopAll() public void StopAll(bool destroy = false)
{ {
foreach (Util.Sound sound in playingSounds) foreach (Util.Sound sound in playingSounds)
{ {
sound.Stop(); sound.Stop();
} }
if (destroy)
{
Destroy(gameObject);
}
} }
} }
} }