using UdonSharp; using UnityEngine; using VRC.SDKBase; using VRC.Udon; public class SoundManager : UdonSharpBehaviour { [SerializeField] private AudioSource audioSourcePacMan; [SerializeField] private AudioSource audioSourceGhosts; [SerializeField] private AudioSource audioSourceExtraLife; [SerializeField] private AudioClip pacStart; [SerializeField] private AudioClip pacDot1; [SerializeField] private AudioClip pacDot2; [SerializeField] private AudioClip pacDie1; [SerializeField] private AudioClip pacFruit; [SerializeField] private AudioClip pacCoin; [SerializeField] private AudioClip pacGhostEat; [SerializeField] private AudioClip pacGhost1; [SerializeField] private AudioClip pacGhostBlue; [SerializeField] private AudioClip pacGhostRetreat; [SerializeField] private AudioClip pacExtraLife; private AudioClip _nextDotSound; private bool _isRetreating; private bool _isBlue; private bool _suppress; public void Initialize() { Reset(); } public void Reset() { StopAllSound(); _nextDotSound = pacDot2; _isRetreating = false; _isBlue = false; _suppress = true; } public void SuppressSound(bool suppress) { _suppress = suppress; if (suppress) { StopAllSound(); } } public void PlayGameStartSound() { PlaySound(audioSourcePacMan, pacStart); } public void PlayPelletSound() { PlaySound(audioSourcePacMan, _nextDotSound); _nextDotSound = _nextDotSound == pacDot1 ? pacDot2 : pacDot1; } public void PlayDeathSound() { PlaySound(audioSourcePacMan, pacDie1); } public void PlayFruitSound() { PlaySound(audioSourcePacMan, pacFruit); } public void PlayCoinSound() { PlaySound(audioSourcePacMan, pacCoin); } public void PlayGhostEatSound() { PlaySound(audioSourcePacMan, pacGhostEat); } public void PlayExtraLifeSound() { PlaySound(audioSourceExtraLife, pacExtraLife); } public void StartGhostSound(bool isBlue) { Debug.Log($"Start ghost sound, isBlue: {isBlue}, _isRetreating: {_isRetreating}, _suppress: {_suppress}"); _isBlue = isBlue; if (_isRetreating) { // Retreating overrides other ghost sound return; } var sound = _isBlue ? pacGhostBlue : pacGhost1; PlaySound(audioSourceGhosts, sound, true); } public void StartGhostRetreat() { _isRetreating = true; PlaySound(audioSourceGhosts, pacGhostRetreat, true); } public void EndGhostRetreat() { Debug.Log("End ghost retreating"); if (!_isRetreating) { return; } _isRetreating = false; StartGhostSound(_isBlue); } public void StopAllSound() { audioSourcePacMan.Stop(); audioSourceGhosts.Stop(); // audioSourceExtraLife is not stopped on purpose, this sound is never interrupted } private void PlaySound(AudioSource audioSource, AudioClip audioClip, bool loop = false) { // Debug.Log($"PlaySound, audioSource: {audioSource}, audioClip: {audioClip}, loop: {loop}, suppress: {_suppress}"); if (_suppress) { return; } if (loop && audioSource.clip == audioClip && audioSource.isPlaying) { // Don't restart a looping sound return; } audioSource.clip = audioClip; audioSource.Play(); audioSource.loop = loop; } }