Universal Sound Player for Unity

Summary

A Sound Player for Unity that can be called from anywhere once placed in the scene. Especially useful for UI sounds and such, but pretty versatile beyond that as it contains settings for multiple different types of sounds (effects, dialogue, etc) and is easily expandable.

It even has some use in 3D gaming as the GetVolume aspects are still static functions. Meaning any AudioSource can modify its volume, accordingly.

Script

Full script below (Creative Commons 4.0)

//ArmanDoesStuff 2017
using System.Collections.Generic;
using UnityEngine;


namespace ArmanDoesStuff.Core
{
    public class SoundPlayer : MonoBehaviour
    {
        #region variables
        [HideInInspector] public static SoundPlayer instance;
        private List<AudioSource> sources = new List<AudioSource>();
        public enum SoundTypes { master, general, effect, dialogue, music };
        [HideInInspector] public float[] soundVolumes;
        #endregion

        #region accessors
        public bool IsPlaying
        {
            get
            {
                foreach (AudioSource a in sources)
                {
                    if (a.isPlaying)
                    {
                        return true;
                    }
                }
                return false;
            }
        }

        #endregion

        #region functions

        private void Awake()
        {
            if (instance == null)
            {
                instance = this;
            }
            else
            {
                Debug.LogError("Error: Master Instance already set at " + instance.gameObject.name);
                Destroy(this);
            }
            //The soundVolumes array needs to be set somewhere, or you will get a NullReference. By default I use:
            //instance.soundVolumes = new float[System.Enum.GetValues(typeof(SoundPlayer.SoundTypes)).Length];
        }

        public static void ClearSounds()
        {
            //Removes all items in the list where item == null (has been destroye)
            //Make sure you do this BEFORE rather than after as they will not be null untill the next frame
            instance.sources.RemoveAll(item => item == null);
            foreach (AudioSource a in instance.sources)
            {
                if (!a.isPlaying)
                {
                    Destroy(a);
                }
            }
        }

        public static void ClearAllSounds()
        {
            instance.sources.RemoveAll(item => item == null);
            foreach (AudioSource a in instance.sources)
            {
                Destroy(a);
            }
        }

        public static float GetVolume(SoundTypes _type)
        {
            return instance.soundVolumes[(int)_type];
        }

        public static void SetVolume(SoundTypes _type = SoundTypes.general, float _vol = 1)
        {
            instance.soundVolumes[(int)_type] = _vol;
            switch (_type)
            {
                case SoundTypes.master:
                    AudioListener.volume = _vol;
                    break;
                case SoundTypes.music:
                    FindObjectOfType<MusicPlayer>().Volume = _vol;
                    break;
                default:
                    break;
            }
        }

        public void Play(AudioClip _clip) //for use with buttons
        {
            Play(_clip, SoundTypes.general);
        }

        public static AudioSource Play(AudioClip _clip, SoundTypes _type = SoundTypes.general, float _pitch = 1, float _mult = 1)
        {
            float vol = instance.soundVolumes[(int)_type];
            AudioSource audS = instance.gameObject.AddComponent<AudioSource>();
            audS.pitch = _pitch;
            audS.volume = vol * _mult; //maybe * by master volume if doing PC game, also update the audioclip extention
            audS.clip = _clip;
            audS.Play();
            ClearSounds();
            instance.sources.Add(audS);
            return audS;
        }

        public static AudioSource PlayRandom(List<AudioClip> _clips, SoundTypes _type = SoundTypes.general, float _pitch = 1, float _mult = 1)
        {
            return PlayRandom(_clips.ToArray(), _type, _pitch, _mult);
        }

        public static AudioSource PlayRandom(AudioClip[] _clips, SoundTypes _type = SoundTypes.general, float _pitch = 1, float _mult = 1)
        {
            return Play(_clips[Random.Range(0, _clips.Length)], _type, _pitch, _mult);
        }
        #endregion
    }
}

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.