I'm glad you enjoyed it!
Here's some code for you for the audio sync stuff - it's pretty straightforward, feel free to ask any questions:
public class IntEvent : UnityEvent<int>{ } public class AudioBeatManager : MonoBehaviour { [SerializeField] private float bpm; private float _secPerBeat; public float TimeBetweenBeats => _secPerBeat; private int _currentBeat = 0; private float _timer; [SerializeField] private IntEvent onBeat; public IntEvent OnBeat => onBeat; public event Action<int> OnBeatEvent; private float _initialPower; private float _startTime; public float DspTime => (float) AudioSettings.dspTime - _startTime; private void Awake() { _secPerBeat = 60f / bpm; } private void OnEnable() { _startTime = (float) AudioSettings.dspTime; _currentBeat = 0; } private void Start() { _timer = 0; } public void SetBPM(int newBpm, bool resetCurrentBeat = false) { bpm = newBpm; _secPerBeat = 60f / bpm; if (resetCurrentBeat) _currentBeat = 0; Start(); } public void DoReset() { bpm = _originalBpm; _secPerBeat = 60f / bpm; Start(); _currentBeat = 0; _startTime = (float) AudioSettings.dspTime; } void Update() { // new beats var beatsElapsed = (int)(DspTime / TimeBetweenBeats); var lastBeatTime = beatsElapsed * TimeBetweenBeats; var timeSinceLastBeat = DspTime - lastBeatTime; if (beatsElapsed > _currentBeat) { // a beat gone done did do happen // account for this frame being a little bit past the beat! _timer = timeSinceLastBeat; ++_currentBeat; if (Time.timeScale == 0) return; OnBeat?.Invoke(_currentBeat); OnBeatEvent?.Invoke(_currentBeat); } } }
I've stripped out a couple of things you wont need, so if there are any errors let me know what they are xD it's probably because I've taken something important out ;)