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.
CrowdControl/Assets/Feel/MMTools/Tools/MMAudio/MMSoundManager/MMSoundManagerAudioPool.cs

129 lines
3.5 KiB
C#

3 months ago
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;
}
}
}