//you could do this with a dictionary, but ill use a list. using System.Linq; [CreateAssetMenu(FileName = "AudioClipList"); class ClipList : ScriptableObject { public string listName; public List Clips = new List(); public bool Contains (String name) => Clips.Any(c => c.name == name); public Clip GetClip(String name) { var list = Clips.Where(c => c.name == name).ToList(); return list.Length>0? list[0]:null; } //if there is a clip and it is not null or missing remove it public void RemoveClip(String name) => if (GetClip(name) is Clip c) Clips.Remove(c); public void AddClip(string name, AudioClip clip) => if (!Clips.Contains(name)) Clips.Add(new Clip(){ name = name, audioClip = clip }); public void AddClip(Clip clip) => if (clip != null && !Contains(clip.name)) Clip.Add(clip); } //this attribute makes the normal class able to show up in the inspector [System.Serializable] public class Clip { public string name; public string type; public AudioClip audioClip; public bool playing, paused; } [CreateAssetMenu(MenuName="Audio/MixerPreset"] public class MixerPreset : ScriptableObject { public string Name; public AudioMixer mixer; public AudioSource prefab; //Assuming a mixer can be made up of a series of audio sources List audioSources = new List(); public ClipsList clips; public void PlayClip(string name) { var clip = clips.GetClip(name); if (clip ==null || clip.playing) return; StartCoroutine("PlaySoundCoroutine", clip); } public void Pause(string name) { var clip = clips.GetClip(name); if (clip ==null) return; var sources =audioSources.Where(a=>a.clip== clip.clip).ToList(); if (sources.Length == 0) return; sources[0].Pause(); clip.paused = true; } public void RestartSound(string name) { var clip = clips.GetClip(name); if (clip ==null) return; var sources = audioSources.Where(a=>a.clip == clip.clip).ToList(); if(sources.Length==0)return; sources[0].Pause(); sources[0].time =0; sources[0].Unpause(); } public void UnpauseSound(string name){ var clip = clips.GetClip(name); if (clip ==null) return; var sources = audioSources.Where(a=>a.clip == clip.clip).ToList(); if (sources.Length ==0) return; sources[0].Unpause(); clip.paused = false; } Ienumerator PlaySoundCoroutine (Clip clip) { List inactiveSources = audioSources.Where(a=>!a.enabled).ToList(); AudioSource source = inactiveSources.Length >0? inactiveSources[0] : AudioSource.Instantiate(audioSourcePrefab); source.SetActive(true); source.outputAudioMixerGroup = mixer; source.playOneShot(clip.clip); //keep audio source active while a clip is playing or paused while(source.isPlaying || clip.paused) { yield return null; } source.SetActive(false); clip.playing = false; } class AudioManager : MonoBehaviour { public static void PlayPresetClip(MixerPreset mixerPreset, string clip) => mixerPreset.Play(clip); public MixerPreset mixerPreset; //this will give you a slot to place a mixerpreset }