2021-12-19 04:10:43 +00:00
|
|
|
using System.Collections;
|
|
|
|
using System.Collections.Generic;
|
|
|
|
using UnityEngine;
|
2021-12-31 06:56:51 +00:00
|
|
|
using UnityEngine.Audio;
|
2021-12-19 04:10:43 +00:00
|
|
|
|
|
|
|
using Starpelly;
|
|
|
|
|
2021-12-21 01:10:49 +00:00
|
|
|
namespace RhythmHeavenMania
|
2021-12-19 04:10:43 +00:00
|
|
|
{
|
2022-01-03 22:42:43 +00:00
|
|
|
// [RequireComponent(typeof(AudioSource))]
|
2021-12-21 01:10:49 +00:00
|
|
|
public class Conductor : MonoBehaviour
|
|
|
|
{
|
2022-01-07 11:36:23 +00:00
|
|
|
// Song beats per minute
|
|
|
|
// This is determined by the song you're trying to sync up to
|
2021-12-21 01:10:49 +00:00
|
|
|
public float songBpm;
|
2021-12-19 04:10:43 +00:00
|
|
|
|
2022-01-07 11:36:23 +00:00
|
|
|
// The number of seconds for each song beat
|
2021-12-21 01:10:49 +00:00
|
|
|
public float secPerBeat;
|
2021-12-19 04:10:43 +00:00
|
|
|
|
2022-01-07 11:36:23 +00:00
|
|
|
// Current song position, in seconds
|
2021-12-21 01:10:49 +00:00
|
|
|
public float songPosition;
|
2021-12-19 04:10:43 +00:00
|
|
|
|
2022-01-07 11:36:23 +00:00
|
|
|
// Current song position, in beats
|
2021-12-21 01:10:49 +00:00
|
|
|
public float songPositionInBeats;
|
2021-12-19 04:10:43 +00:00
|
|
|
|
2022-01-07 11:36:23 +00:00
|
|
|
// Current time of the song
|
|
|
|
private float time;
|
2021-12-19 04:10:43 +00:00
|
|
|
|
2022-01-07 11:36:23 +00:00
|
|
|
// an AudioSource attached to this GameObject that will play the music.
|
|
|
|
public AudioSource musicSource;
|
2021-12-19 04:10:43 +00:00
|
|
|
|
2022-01-07 11:36:23 +00:00
|
|
|
// The offset to the first beat of the song in seconds
|
|
|
|
public float firstBeatOffset;
|
2021-12-19 04:10:43 +00:00
|
|
|
|
2022-01-07 11:36:23 +00:00
|
|
|
// Conductor instance
|
2021-12-21 01:10:49 +00:00
|
|
|
public static Conductor instance;
|
2021-12-19 04:10:43 +00:00
|
|
|
|
2022-01-15 17:45:08 +00:00
|
|
|
// Conductor is currently playing song
|
2022-01-07 11:36:23 +00:00
|
|
|
public bool isPlaying;
|
2022-01-15 17:45:08 +00:00
|
|
|
|
|
|
|
// Conductor is currently paused, but not fully stopped
|
2022-01-07 11:36:23 +00:00
|
|
|
public bool isPaused;
|
|
|
|
|
2022-01-15 17:45:08 +00:00
|
|
|
// Last reported beat based on song position
|
|
|
|
private float lastReportedBeat = 0f;
|
|
|
|
|
|
|
|
// Metronome tick sound enabled
|
|
|
|
public bool metronome = false;
|
|
|
|
|
2022-01-19 05:40:49 +00:00
|
|
|
private bool beat;
|
|
|
|
|
2022-01-07 11:36:23 +00:00
|
|
|
// private AudioDspTimeKeeper timeKeeper;
|
2021-12-28 02:36:27 +00:00
|
|
|
|
2021-12-21 01:10:49 +00:00
|
|
|
void Awake()
|
|
|
|
{
|
|
|
|
instance = this;
|
|
|
|
}
|
2021-12-19 04:10:43 +00:00
|
|
|
|
2021-12-21 01:10:49 +00:00
|
|
|
void Start()
|
|
|
|
{
|
|
|
|
secPerBeat = 60f / songBpm;
|
2022-01-07 11:36:23 +00:00
|
|
|
}
|
|
|
|
|
2022-01-08 16:42:48 +00:00
|
|
|
public void SetBeat(float beat)
|
2022-01-07 11:36:23 +00:00
|
|
|
{
|
2022-01-08 16:42:48 +00:00
|
|
|
float secFromBeat = GetSongPosFromBeat(beat);
|
2021-12-19 04:10:43 +00:00
|
|
|
|
2022-01-09 23:35:55 +00:00
|
|
|
if (musicSource.clip != null)
|
|
|
|
{
|
|
|
|
if (secFromBeat < musicSource.clip.length)
|
|
|
|
musicSource.time = secFromBeat;
|
|
|
|
else
|
|
|
|
musicSource.time = 0;
|
|
|
|
}
|
2022-01-07 23:51:08 +00:00
|
|
|
|
2022-01-08 16:42:48 +00:00
|
|
|
GameManager.instance.SetCurrentEventToClosest(beat);
|
2022-01-07 23:51:08 +00:00
|
|
|
}
|
|
|
|
|
2022-01-08 16:42:48 +00:00
|
|
|
public void Play(float beat)
|
2022-01-07 23:51:08 +00:00
|
|
|
{
|
2022-01-08 16:42:48 +00:00
|
|
|
this.time = GetSongPosFromBeat(beat);
|
2022-01-07 11:36:23 +00:00
|
|
|
|
|
|
|
isPlaying = true;
|
|
|
|
isPaused = false;
|
|
|
|
|
2022-01-08 16:42:48 +00:00
|
|
|
if (SongPosLessThanClipLength(time))
|
|
|
|
{
|
|
|
|
musicSource.time = time;
|
|
|
|
musicSource.PlayScheduled(Time.time);
|
|
|
|
}
|
|
|
|
|
2022-01-14 02:33:51 +00:00
|
|
|
// GameManager.instance.SetCurrentEventToClosest(songPositionInBeats);
|
2021-12-21 01:10:49 +00:00
|
|
|
}
|
2021-12-19 04:10:43 +00:00
|
|
|
|
2022-01-07 11:36:23 +00:00
|
|
|
public void Pause()
|
2021-12-28 02:36:27 +00:00
|
|
|
{
|
2022-01-07 11:36:23 +00:00
|
|
|
isPlaying = false;
|
|
|
|
isPaused = true;
|
|
|
|
|
|
|
|
musicSource.Pause();
|
|
|
|
}
|
|
|
|
|
2022-01-08 16:42:48 +00:00
|
|
|
public void Stop(float time)
|
2022-01-07 11:36:23 +00:00
|
|
|
{
|
2022-01-08 16:42:48 +00:00
|
|
|
this.time = time;
|
2022-01-07 11:36:23 +00:00
|
|
|
isPlaying = false;
|
|
|
|
isPaused = false;
|
|
|
|
|
2022-01-07 23:51:08 +00:00
|
|
|
|
2022-01-07 11:36:23 +00:00
|
|
|
musicSource.Stop();
|
2021-12-31 14:46:11 +00:00
|
|
|
}
|
|
|
|
|
2021-12-27 04:48:39 +00:00
|
|
|
public void Update()
|
2021-12-19 04:10:43 +00:00
|
|
|
{
|
2022-01-07 11:36:23 +00:00
|
|
|
if (isPlaying)
|
|
|
|
{
|
|
|
|
time += Time.deltaTime * musicSource.pitch;
|
2021-12-19 04:10:43 +00:00
|
|
|
|
2022-01-07 23:51:08 +00:00
|
|
|
songPosition = time - firstBeatOffset;
|
2021-12-19 04:10:43 +00:00
|
|
|
|
2022-01-07 11:36:23 +00:00
|
|
|
songPositionInBeats = songPosition / secPerBeat;
|
2022-01-15 17:45:08 +00:00
|
|
|
|
|
|
|
if (metronome)
|
|
|
|
{
|
2022-01-19 05:40:49 +00:00
|
|
|
if (ReportBeat(ref lastReportedBeat))
|
2022-01-15 17:45:08 +00:00
|
|
|
{
|
2022-01-19 05:40:49 +00:00
|
|
|
Util.Jukebox.PlayOneShot("metronome");
|
2022-01-15 17:45:08 +00:00
|
|
|
}
|
|
|
|
else if (songPosition <= lastReportedBeat)
|
|
|
|
{
|
|
|
|
lastReportedBeat = (songPosition - (songPosition % secPerBeat));
|
|
|
|
}
|
|
|
|
}
|
2022-01-07 11:36:23 +00:00
|
|
|
}
|
2021-12-21 01:10:49 +00:00
|
|
|
}
|
2021-12-19 04:10:43 +00:00
|
|
|
|
2022-01-19 05:40:49 +00:00
|
|
|
public bool ReportBeat(ref float lastReportedBeat, float offset = 0)
|
|
|
|
{
|
|
|
|
bool result = songPosition > (lastReportedBeat + offset) + secPerBeat;
|
|
|
|
if (result == true)
|
|
|
|
{
|
|
|
|
lastReportedBeat = (songPosition - (songPosition % secPerBeat) + offset);
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2021-12-21 01:10:49 +00:00
|
|
|
public float GetLoopPositionFromBeat(float startBeat, float length)
|
|
|
|
{
|
2021-12-27 04:48:39 +00:00
|
|
|
float a = Mathp.Normalize(songPositionInBeats, startBeat, startBeat + length);
|
|
|
|
return a;
|
2021-12-21 01:10:49 +00:00
|
|
|
}
|
|
|
|
|
2022-01-07 23:51:08 +00:00
|
|
|
public float GetSongPosFromBeat(float beat)
|
2021-12-31 14:46:11 +00:00
|
|
|
{
|
|
|
|
return secPerBeat * beat;
|
|
|
|
}
|
|
|
|
|
2021-12-23 02:28:05 +00:00
|
|
|
public void SetBpm(float bpm)
|
|
|
|
{
|
|
|
|
this.songBpm = bpm;
|
|
|
|
secPerBeat = 60f / songBpm;
|
|
|
|
}
|
2022-01-06 00:11:33 +00:00
|
|
|
|
|
|
|
public float SongLengthInBeats()
|
|
|
|
{
|
2022-01-07 11:36:23 +00:00
|
|
|
if (!musicSource.clip) return 0;
|
2022-01-06 00:11:33 +00:00
|
|
|
return musicSource.clip.length / secPerBeat;
|
|
|
|
}
|
2022-01-08 16:42:48 +00:00
|
|
|
|
|
|
|
public bool SongPosLessThanClipLength(float t)
|
|
|
|
{
|
2022-01-09 23:35:55 +00:00
|
|
|
if (musicSource.clip != null)
|
|
|
|
return t < musicSource.clip.length;
|
|
|
|
else
|
|
|
|
return false;
|
2022-01-08 16:42:48 +00:00
|
|
|
}
|
2022-01-11 00:17:29 +00:00
|
|
|
|
|
|
|
public bool NotStopped()
|
|
|
|
{
|
2022-01-17 02:31:49 +00:00
|
|
|
return Conductor.instance.isPlaying == true || Conductor.instance.isPaused == true;
|
2022-01-11 00:17:29 +00:00
|
|
|
}
|
2021-12-19 04:10:43 +00:00
|
|
|
}
|
|
|
|
}
|