UnityGameProjectsCode / Rise2Point0Game / Managers / SoundManager.cs
SoundManager.cs
Raw
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;
    }
}