You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
129 lines
3.5 KiB
C#
129 lines
3.5 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using UnityEngine.Audio;
|
|
using UnityEngine.SceneManagement;
|
|
|
|
namespace MoreMountains.Tools
|
|
{
|
|
/// <summary>
|
|
/// This class manages an object pool of audiosources
|
|
/// </summary>
|
|
[Serializable]
|
|
public class MMSoundManagerAudioPool
|
|
{
|
|
protected List<AudioSource> _pool;
|
|
|
|
/// <summary>
|
|
/// Fills the pool with ready-to-use audiosources
|
|
/// </summary>
|
|
/// <param name="poolSize"></param>
|
|
/// <param name="parent"></param>
|
|
public virtual void FillAudioSourcePool(int poolSize, Transform parent)
|
|
{
|
|
if (_pool == null)
|
|
{
|
|
_pool = new List<AudioSource>();
|
|
}
|
|
|
|
if ((poolSize <= 0) || (_pool.Count >= poolSize))
|
|
{
|
|
return;
|
|
}
|
|
|
|
foreach (AudioSource source in _pool)
|
|
{
|
|
UnityEngine.Object.Destroy(source.gameObject);
|
|
}
|
|
|
|
for (int i = 0; i < poolSize; i++)
|
|
{
|
|
GameObject temporaryAudioHost = new GameObject("MMAudioSourcePool_"+i);
|
|
SceneManager.MoveGameObjectToScene(temporaryAudioHost.gameObject, parent.gameObject.scene);
|
|
AudioSource tempSource = temporaryAudioHost.AddComponent<AudioSource>();
|
|
MMFollowTarget followTarget = temporaryAudioHost.AddComponent<MMFollowTarget>();
|
|
followTarget.enabled = false;
|
|
followTarget.DisableSelfOnSetActiveFalse = true;
|
|
temporaryAudioHost.transform.SetParent(parent);
|
|
temporaryAudioHost.SetActive(false);
|
|
_pool.Add(tempSource);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Disables an audio source after it's done playing
|
|
/// </summary>
|
|
/// <param name="duration"></param>
|
|
/// <param name="targetObject"></param>
|
|
/// <returns></returns>
|
|
public virtual IEnumerator AutoDisableAudioSource(float duration, AudioSource source, AudioClip clip, bool doNotAutoRecycleIfNotDonePlaying, float playbackTime, float playbackDuration)
|
|
{
|
|
float initialWait = (playbackDuration > 0) ? playbackDuration : duration;
|
|
yield return MMCoroutine.WaitFor(initialWait);
|
|
if (source.clip != clip)
|
|
{
|
|
yield break;
|
|
}
|
|
if (doNotAutoRecycleIfNotDonePlaying)
|
|
{
|
|
float maxTime = (playbackDuration > 0) ? playbackTime + playbackDuration : source.clip.length;
|
|
while (source.time < maxTime)
|
|
{
|
|
yield return null;
|
|
}
|
|
}
|
|
source.gameObject.SetActive(false);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Pulls an available audio source from the pool
|
|
/// </summary>
|
|
/// <param name="poolCanExpand"></param>
|
|
/// <param name="parent"></param>
|
|
/// <returns></returns>
|
|
public virtual AudioSource GetAvailableAudioSource(bool poolCanExpand, Transform parent)
|
|
{
|
|
foreach (AudioSource source in _pool)
|
|
{
|
|
if (!source.gameObject.activeInHierarchy)
|
|
{
|
|
source.gameObject.SetActive(true);
|
|
return source;
|
|
}
|
|
}
|
|
|
|
if (poolCanExpand)
|
|
{
|
|
GameObject temporaryAudioHost = new GameObject("MMAudioSourcePool_"+_pool.Count);
|
|
SceneManager.MoveGameObjectToScene(temporaryAudioHost.gameObject, parent.gameObject.scene);
|
|
AudioSource tempSource = temporaryAudioHost.AddComponent<AudioSource>();
|
|
temporaryAudioHost.transform.SetParent(parent);
|
|
temporaryAudioHost.SetActive(true);
|
|
_pool.Add(tempSource);
|
|
return tempSource;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Stops an audiosource and returns it to the pool
|
|
/// </summary>
|
|
/// <param name="sourceToStop"></param>
|
|
/// <returns></returns>
|
|
public virtual bool FreeSound(AudioSource sourceToStop)
|
|
{
|
|
foreach (AudioSource source in _pool)
|
|
{
|
|
if (source == sourceToStop)
|
|
{
|
|
source.Stop();
|
|
source.gameObject.SetActive(false);
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
}
|
|
} |