using System.Collections.Generic; using System.Linq; using TMPro; using UnityEngine; using UnityEngine.UI; public class SoundManager : MonoBehaviour { public List<AudioClip> uiEffects = new List<AudioClip>(); public List<AudioClip> musicClips = new List<AudioClip>(); public List<AudioClip> scoreIncreases = new List<AudioClip>(); public List<AudioClip> deathSounds = new List<AudioClip>(); public AudioClip musicTitleSlideUpSound; public AudioClip musicTitleSlideDownSound; public AudioClip achievementPing; public GameObject musicEntryPrefab; private int currentMusicTrackID = -1; private bool musicPaused = false; private bool shuffleEnabled = true; private bool loopEnabled = true; private float trackStopTime; private float timeSinceMusicStart; private List<GameObject> boardEntries = new List<GameObject>(); private List<int> loopTracksPlayed = new List<int>(); //used to track what songs have been played when loop is disabled private List<int> trackPlayOrder = new List<int>(); //used to track the order that songs have been played in private int trackReverseDepth = 0; //used to track how far back the player has gone into the play order private int currentPlayableTracks; //tracks the number of songs that are currently unlocked public Sprite shuffleOffSprite; public Sprite shuffleOnSprite; public Sprite loopOffSprite; public Sprite loopOnSprite; public Sprite playButtonSprite; public Sprite pauseButtonSprite; public Image shuffleImage; public Image shuffleGamePlayImage; public Image loopImage; public Image loopGamePlayImage; public Image playPauseImage; public Scrollbar musicScroll; private List<string> savedMusicNames = new List<string>(); private List<bool> savedMusicFavorites = new List<bool>(); private List<string> defaultMusicOrder = new List<string>(); private List<bool> savedMusicLockStates = new List<bool>(); private AudioSource musicAudioSource; public AudioSource scoreAudioSource; public AudioSource uiAudioSource; public AudioSource deathAudioSource; public AudioSource notificationAudioSource; private GameObject muteIcon; private TextMeshProUGUI songTitleText; private Animator musicAnims; private GameObject musicBoardContent; private void Awake() { musicAudioSource = GetComponent<AudioSource>(); musicAnims = GetComponent<Animator>(); for (int i = 0; i < savedMusicNames.Count; i++) { savedMusicNames[i] = ""; } for (int i = 0; i < musicClips.Count; i++) { defaultMusicOrder.Add(musicClips[i].name); } } private void Start() { muteIcon = GUIManager.GetObject(10); musicBoardContent = GUIManager.GetObject(36); songTitleText = GUIManager.GetObject(11).GetComponent<TextMeshProUGUI>(); } private void Update() { if (!musicPaused) { if (musicAudioSource.isPlaying == false) { PlayNextMusicTrack(); } timeSinceMusicStart += Time.deltaTime; if (trackPlayOrder.Count > 15) { CleanupTrackOrderList(); } } } public void AddAllCurrentTracksToBoard() { //adds all tracks currently available to the music board for (int i = 0; i < musicClips.Count; i++) { if (i < 29) { AddMusicEntryToBoard(musicClips[i].name, false, false); currentPlayableTracks = i; } else //any track above 28 is an unlock song AddMusicEntryToBoard(musicClips[i].name, false, true); } //SetExplicitButtonNavigation(); } public void AddMusicEntryToBoard(string songName, bool isFav, bool isLocked) { //adds a single tracks information to the music board //instatiate the object GameObject newEntry = Instantiate(musicEntryPrefab as GameObject, musicBoardContent.transform); //add it to a list of objects boardEntries.Add(newEntry); //access the info attached to the object MusicEntryInfo newEntryInfo = newEntry.GetComponent<MusicEntryInfo>(); //set the info for the object newEntryInfo.SetEntryID(boardEntries.Count - 1); newEntryInfo.SetIsFavorite(isFav); newEntryInfo.SetSongName(songName); newEntryInfo.SetIsLocked(isLocked); //add the object info to a list of saved info savedMusicNames.Add(songName); savedMusicFavorites.Add(isFav); savedMusicLockStates.Add(isLocked); //call to the save manager to update the saved values SaveManager.SaveMusicBoardEntries(savedMusicNames, savedMusicFavorites, savedMusicLockStates); } public void AddSavedMusicEntriesToBoard(List<string> savedNames, List<bool> savedFavorites, List<bool> savedLockStates) { //called from savemanager via the gamemanager to add any saved music entries to the board List<AudioClip> tempMusicClips = new List<AudioClip>(); for (int i = 0; i < savedNames.Count; i++) { GameObject entry = Instantiate(musicEntryPrefab as GameObject, musicBoardContent.transform); boardEntries.Add(entry); MusicEntryInfo newEntryInfo = entry.GetComponent<MusicEntryInfo>(); newEntryInfo.SetEntryID(i); newEntryInfo.SetIsFavorite(savedFavorites[i]); newEntryInfo.SetSongName(savedNames[i]); newEntryInfo.SetIsLocked(savedLockStates[i]); savedMusicNames.Add(savedNames[i]); savedMusicFavorites.Add(savedFavorites[i]); savedMusicLockStates.Add(savedLockStates[i]); //store saved song order into a temp list and then overwrite the main list AudioClip clipToAdd = null; for (int y = 0; y < musicClips.Count; y++) { if (musicClips[y].name == newEntryInfo.GetSongName()) clipToAdd = musicClips[y]; } tempMusicClips.Add(clipToAdd); if (savedLockStates[i] == false) currentPlayableTracks++; } musicClips = tempMusicClips; //SetExplicitButtonNavigation(); } public void SetLoopAndShuffleStates(bool loopState, bool shuffleState) { shuffleEnabled = shuffleState; if (shuffleEnabled == false) { shuffleImage.sprite = shuffleOffSprite; shuffleGamePlayImage.sprite = shuffleOffSprite; } else { shuffleImage.sprite = shuffleOnSprite; shuffleGamePlayImage.sprite = shuffleOnSprite; } loopEnabled = loopState; if (loopEnabled == false) { loopImage.sprite = loopOffSprite; loopGamePlayImage.sprite = loopOffSprite; } else { loopImage.sprite = loopOnSprite; loopGamePlayImage.sprite = loopOnSprite; } SaveManager.SaveMusicBoardLoopState(loopEnabled); SaveManager.SaveMusicBoardShuffleState(shuffleEnabled); } /* public void SetExplicitButtonNavigation() { //for each added board entry set the explicit movement for buttons. int indexID = 0; foreach (GameObject musicEntry in boardEntries) { MusicEntryInfo entryInfo = musicEntry.GetComponent<MusicEntryInfo>(); if (indexID == 0) { entryInfo.SetUpExplicitTargets(null, entryInfo.GetDownButton().gameObject, musicScroll.gameObject); entryInfo.SetDownExplicitTargets(entryInfo.GetUpButton().gameObject, boardEntries[indexID + 1].GetComponent<MusicEntryInfo>().GetUpButton().gameObject, musicScroll.gameObject); indexID++; } else if (indexID < boardEntries.Count - 1) { entryInfo.SetUpExplicitTargets(boardEntries[indexID - 1].GetComponent<MusicEntryInfo>().GetDownButton().gameObject, entryInfo.GetDownButton().gameObject, musicScroll.gameObject); entryInfo.SetDownExplicitTargets(entryInfo.GetUpButton().gameObject, boardEntries[indexID + 1].GetComponent<MusicEntryInfo>().GetUpButton().gameObject, musicScroll.gameObject); indexID++; } else if (indexID == boardEntries.Count - 1) { entryInfo.SetUpExplicitTargets(boardEntries[indexID - 1].GetComponent<MusicEntryInfo>().GetDownButton().gameObject, entryInfo.GetDownButton().gameObject, musicScroll.gameObject); entryInfo.SetDownExplicitTargets(entryInfo.GetUpButton().gameObject, null, musicScroll.gameObject); } } var scrollNav = musicScroll.navigation; scrollNav.selectOnLeft = boardEntries[0].GetComponent<MusicEntryInfo>().GetUpButton(); musicScroll.navigation = scrollNav; } */ public void ClearMusicBoardEntries() { for (int i = boardEntries.Count - 1; i >= 0; i--) { Destroy(boardEntries[i]); } boardEntries.Clear(); savedMusicNames.Clear(); savedMusicFavorites.Clear(); savedMusicLockStates.Clear(); SaveManager.DeleteMusicBoardEntries(); for (int i = 0; i < savedMusicNames.Count; i++) { savedMusicNames[i] = ""; } //create a temp list to store the songs in the right order List<AudioClip> tempClips = new List<AudioClip>(); //go through the music list and find songs by name. Add them in the order specified by the default order list for (int i = 0; i < defaultMusicOrder.Count; i++) { for (int y = 0; y < musicClips.Count; y++) { if (defaultMusicOrder[i] == musicClips[y].name) { tempClips.Add(musicClips[y]); break; } } } //set the music clips list to the temp list musicClips = tempClips; AddAllCurrentTracksToBoard(); } public void ResetShuffleAndLoopStates() { SetLoopAndShuffleStates(true, true); } public void ChangeMusicEntryPosition(MusicEntryInfo targetEntry, int changeValue) { //based on the changeValue, edit the music boards information to reflect the target entry moving up or down //swap with the adjacent entry int newPositionIndex; if (changeValue == -1) //swap with the entry below this one newPositionIndex = targetEntry.GetEntryID() + 1; else newPositionIndex = targetEntry.GetEntryID() - 1; string swapName = savedMusicNames[newPositionIndex]; bool swapFav = savedMusicFavorites[newPositionIndex]; bool swapLock = savedMusicLockStates[newPositionIndex]; AudioClip swapClip = musicClips[newPositionIndex]; AudioClip targetClip = musicClips[targetEntry.GetEntryID()]; //set the target entries info to the new position MusicEntryInfo swapEntry = boardEntries[newPositionIndex].GetComponent<MusicEntryInfo>(); swapEntry.SetSongName(targetEntry.GetSongName()); swapEntry.SetIsFavorite(targetEntry.GetIsFavorite()); swapEntry.SetIsLocked(targetEntry.GetIsLocked()); //set the swapped information to the old entry targetEntry.SetSongName(swapName); targetEntry.SetIsFavorite(swapFav); targetEntry.SetIsLocked(swapLock); //change the position of the song within the music clips list musicClips[targetEntry.GetEntryID()] = swapClip; musicClips[newPositionIndex] = targetClip; //save the changes to the saved info lists savedMusicNames[newPositionIndex] = swapEntry.GetSongName(); savedMusicFavorites[newPositionIndex] = swapEntry.GetIsFavorite(); savedMusicLockStates[newPositionIndex] = swapEntry.GetIsLocked(); savedMusicNames[targetEntry.GetEntryID()] = swapName; savedMusicFavorites[targetEntry.GetEntryID()] = swapFav; savedMusicLockStates[targetEntry.GetEntryID()] = swapLock; SaveManager.SaveMusicBoardEntries(savedMusicNames, savedMusicFavorites, savedMusicLockStates); } public void ChangeMusicEntryFavoriteState(MusicEntryInfo targetEntry) { bool savedFavState = savedMusicFavorites[targetEntry.GetEntryID()]; if (savedFavState != targetEntry.GetIsFavorite()) { savedMusicFavorites[targetEntry.GetEntryID()] = targetEntry.GetIsFavorite(); SaveManager.SaveMusicBoardEntries(savedMusicNames, savedMusicFavorites, savedMusicLockStates); } } public void CleanupTrackOrderList() { List<int> tempEntries = new List<int>(); for (int i = trackPlayOrder.Count - 11; i < trackPlayOrder.Count; i++) { tempEntries.Add(trackPlayOrder[i]); } trackPlayOrder.Clear(); trackPlayOrder = tempEntries; } public void PauseMusic() { if (!GUIManager.GetUsernameFieldUseState()) { if (!musicPaused) { musicAnims.Play("Music Fade Out"); trackStopTime = timeSinceMusicStart; muteIcon.GetComponent<Animator>().Play("Mute Fade In", 0, 0); musicPaused = true; playPauseImage.sprite = pauseButtonSprite; } else { musicAudioSource.time = trackStopTime; musicAudioSource.Play(); songTitleText.text = "Current Music Track - " + musicAudioSource.clip.name; musicAnims.Play("Music Fade In"); muteIcon.GetComponent<Animator>().Play("Mute Fade Out", 0, 0); songTitleText.GetComponent<Animator>().Play("Song Title Slide", 0, 0); musicPaused = false; playPauseImage.sprite = playButtonSprite; } } } public void StopMusic() { musicAudioSource.Stop(); } public void ReverseShuffleState() { shuffleEnabled = !shuffleEnabled; if (shuffleEnabled == false) { shuffleImage.sprite = shuffleOffSprite; shuffleGamePlayImage.sprite = shuffleOffSprite; } else { shuffleImage.sprite = shuffleOnSprite; shuffleGamePlayImage.sprite = shuffleOnSprite; } SaveManager.SaveMusicBoardShuffleState(shuffleEnabled); } public void ReverseLoopState() { loopEnabled = !loopEnabled; loopTracksPlayed.Clear(); if (loopEnabled == false) { loopImage.sprite = loopOffSprite; loopGamePlayImage.sprite = loopOffSprite; } else { loopImage.sprite = loopOnSprite; loopGamePlayImage.sprite = loopOnSprite; } SaveManager.SaveMusicBoardLoopState(loopEnabled); } public void PlayNextMusicTrack() { if (!GUIManager.GetUsernameFieldUseState()) { if (!musicPaused) { trackStopTime = 0; timeSinceMusicStart = 0; if (!loopEnabled) { if (loopTracksPlayed.Count == currentPlayableTracks && trackReverseDepth == 0) return; } if (trackReverseDepth < 0) { trackReverseDepth++; PlayMusicTrack(trackPlayOrder[trackPlayOrder.Count - Mathf.Abs(trackReverseDepth - 1)]); currentMusicTrackID = trackPlayOrder[trackPlayOrder.Count - Mathf.Abs(trackReverseDepth - 1)]; } else { if (shuffleEnabled) { int randomClip; MusicEntryInfo targetEntry; do { randomClip = Random.Range(0, musicClips.Count); targetEntry = boardEntries[randomClip].GetComponent<MusicEntryInfo>(); } while (randomClip == currentMusicTrackID || targetEntry.GetIsLocked() || trackPlayOrder.Contains(randomClip)); currentMusicTrackID = randomClip; trackPlayOrder.Add(currentMusicTrackID); PlayMusicTrack(randomClip); } else { MusicEntryInfo targetEntry; int newClip = currentMusicTrackID; do { //set the next clip by getting the next track ID after the current track newClip++; //if the next clip ID is outside the bounds of the music clips list, go back to the 0 index if (newClip >= musicClips.Count) newClip = 0; //get the entry info from the board targetEntry = boardEntries[newClip].GetComponent<MusicEntryInfo>(); } while (targetEntry.GetIsLocked()); //if the next song selected is locked, repeat the process until an unlocked clip is found currentMusicTrackID = newClip; trackPlayOrder.Add(currentMusicTrackID); PlayMusicTrack(newClip); } } } else { muteIcon.GetComponent<Animator>().Play("Mute Flash", 0, 0); PlayUIEffect(0.95f, 1.05f); } } } public void PlayLastMusicTrack() { if (!GUIManager.GetUsernameFieldUseState()) { if (!musicPaused) { if (trackPlayOrder.Count > 1) { trackStopTime = 0; timeSinceMusicStart = 0; if (Mathf.Abs(trackReverseDepth) < trackPlayOrder.Count) { trackReverseDepth--; } PlayMusicTrack(trackPlayOrder[trackPlayOrder.Count - Mathf.Abs(trackReverseDepth - 1)]); currentMusicTrackID = trackPlayOrder[trackPlayOrder.Count - Mathf.Abs(trackReverseDepth - 1)]; } else { songTitleText.text = "No tracks found in play history"; songTitleText.GetComponent<Animator>().Play("Song Title Slide", 0, 0); } } else { muteIcon.GetComponent<Animator>().Play("Mute Flash", 0, 0); PlayUIEffect(0.95f, 1.05f); } } } public void PlayMusicTrack(int trackID) { if (!musicPaused) { trackStopTime = 0; timeSinceMusicStart = 0; musicAudioSource.clip = musicClips[trackID]; musicAudioSource.Play(); musicAnims.Play("Music Fade In"); songTitleText.text = musicClips[trackID].name; songTitleText.GetComponent<Animator>().Play("Song Title Slide", 0, 0); if(boardEntries[trackID].GetComponent<MusicEntryInfo>().GetIsFavorite()) songTitleText.GetComponentInChildren<Image>().enabled = true; else songTitleText.GetComponentInChildren<Image>().enabled = false; uiAudioSource.clip = musicTitleSlideUpSound; uiAudioSource.Play(); for (int i = 0; i < boardEntries.Count; i++) { if(i == trackID) boardEntries[i].GetComponent<MusicEntryInfo>().SetCurrentlyPlaying(true); else boardEntries[i].GetComponent<MusicEntryInfo>().SetCurrentlyPlaying(false); } if (!loopEnabled) { loopTracksPlayed.Add(currentMusicTrackID); loopTracksPlayed = loopTracksPlayed.Distinct().ToList(); } } } public void PlayUIEffectDefault() { PlayUIEffect(0.95f, 1.05f); } public void PlayUIEffect(float lowRange, float highRange) { uiAudioSource.clip = uiEffects[Random.Range(0, uiEffects.Count)]; uiAudioSource.pitch = Random.Range(lowRange, highRange); uiAudioSource.Play(); } public void PlayNotificationPing() { notificationAudioSource.clip = achievementPing; notificationAudioSource.Play(); } public void PlayDeathSound() { deathAudioSource.clip = deathSounds[Random.Range(0, deathSounds.Count)]; deathAudioSource.pitch = Random.Range(0.9f, 1.1f); deathAudioSource.Play(); } public void PlayScoreIncreaseSound() { int randomClip = Random.Range(0, scoreIncreases.Count); scoreAudioSource.clip = scoreIncreases[randomClip]; scoreAudioSource.Play(); } public void AddMusicToLibrary(string clipName) { //check the board entries and find the entry that has the same name //see if that entry is locked, if not stop. //if it is locked, unlock it. for (int i = 0; i < boardEntries.Count; i++) { MusicEntryInfo targetEntry = boardEntries[i].GetComponent<MusicEntryInfo>(); if (targetEntry.GetSongName() == clipName) { if (targetEntry.GetIsLocked()) { targetEntry.SetIsLocked(false); savedMusicLockStates[targetEntry.GetEntryID()] = false; currentPlayableTracks++; songTitleText.text = "Added new track: " + clipName; songTitleText.GetComponent<Animator>().Play("Song Title Slide", 0, 0); SaveManager.SaveMusicBoardEntries(savedMusicNames, savedMusicFavorites, savedMusicLockStates); break; } else { songTitleText.text = clipName + " was already added to the playlist"; songTitleText.GetComponent<Animator>().Play("Song Title Slide", 0, 0); break; } } } } public void RemoveMusicFromLibrary(string[] clipNames) { for (int i = 0; i < boardEntries.Count; i++) { for (int y = 0; y < clipNames.Length; y++) { MusicEntryInfo targetEntry = boardEntries[i].GetComponent<MusicEntryInfo>(); if (targetEntry.GetSongName() == clipNames[y]) { targetEntry.SetIsLocked(true); currentPlayableTracks--; } } } songTitleText.text = "Unlocked track(s) removed from the playlist"; songTitleText.GetComponent<Animator>().Play("Song Title Slide", 0, 0); } public float GetMusicVolume() { //get data from the mixer or audio source and return the decebels of the audio return 0; } }