Skip to content

Commit

Permalink
feat: Audio Center api (#96)
Browse files Browse the repository at this point in the history
* feat: Audio center allows to play audio clips using pooled audio sources. + use samples

* chore: added descrbition for the PlayOneShot method

* chore: play one shot descriptions.

* chore: Audio sample updated based on UPM convention.
  • Loading branch information
stan-osipov authored Sep 15, 2022
1 parent b333205 commit 25e5c5d
Show file tree
Hide file tree
Showing 15 changed files with 1,043 additions and 0 deletions.
8 changes: 8 additions & 0 deletions Runtime/Sound.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

78 changes: 78 additions & 0 deletions Runtime/Sound/AudioCenter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
using System;
using StansAssets.Foundation.Extensions;
using StansAssets.Foundation.Patterns;
using UnityEngine;
using Object = UnityEngine.Object;

namespace StansAssets.Foundation.Audio
{
/// <summary>
/// Simple audio manager that allow to play 2D pooled sounds.
/// Common use case is for playing lot's of UI sounds or other game interaction sounds without 3D effect.
/// </summary>
public class AudioCenter
{
readonly GameObject m_Root;
readonly ObjectPool<PooledAudioSource> m_Pool;

/// <summary>
/// Creates new audio center.
/// </summary>
/// <param name="name">Name will be used for the gameobject that will be used as parent for the polled audio sources.</param>
/// <param name="audioListener">The new audio center instance will be parented to the audioListener gameobject. </param>
public AudioCenter(string name, AudioListener audioListener)
: this(name)
{
m_Root.transform.parent = audioListener.transform;
m_Root.transform.Reset();
}

/// <summary>
/// Creates new audio center.
/// </summary>
/// <param name="name">Name will be used for the gameobject that will be used as parent for the polled audio sources.</param>
public AudioCenter(string name)
{
m_Root = new GameObject(name);
Object.DontDestroyOnLoad(m_Root);
m_Pool = new ObjectPool<PooledAudioSource>(() =>
{
var pooledSound = new PooledAudioSource(m_Root.transform);
pooledSound.OnRelease += () =>
{
m_Pool?.Release(pooledSound);
};

return pooledSound;
}, audioSource =>
{
audioSource.Activate();
}, audioSource =>
{
audioSource.Deactivate();
});
}


/// <summary>
/// Will take avaliable pooled audio source to play clip once.
/// The pooled audio source will be released after clip is played.
/// </summary>
/// <param name="clip">The audio clip to play.</param>
public void PlayOneShot(AudioClip clip)
{
m_Pool.Get().PlayOneShot(clip);
}

/// <summary>
/// Get instance of the pooled audio source.
/// You will be responsible for releasing this audio source once you are done using it.
/// </summary>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
public PooledAudioSource GetAudioSource()
{
return m_Pool.Get();
}
}
}
11 changes: 11 additions & 0 deletions Runtime/Sound/AudioCenter.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

61 changes: 61 additions & 0 deletions Runtime/Sound/PooledAudioSource.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
using System;
using StansAssets.Foundation.Async;
using StansAssets.Foundation.Extensions;
using UnityEngine;

namespace StansAssets.Foundation.Audio
{
/// <summary>
/// A pooled wrapper around Unity <see cref="AudioSource"/>.
/// Used as audio source for the <see cref="AudioCenter"/>.
/// You can also obtain a new instance by
/// </summary>
public class PooledAudioSource
{
readonly AudioSource m_AudioSource;
readonly GameObject m_GameObject;
internal event Action OnRelease;

internal PooledAudioSource(Transform root)
{
m_GameObject = new GameObject(nameof(AudioSource));
m_GameObject.transform.parent = root;
m_GameObject.transform.Reset();

m_AudioSource = m_GameObject.AddComponent<AudioSource>();
m_AudioSource.playOnAwake = false;
}

/// <summary>
/// Method will play audo clip once, and as soon as audio clip is played
/// the 'Release' method will be called.
/// </summary>
/// <param name="clip">The audio clip to play.</param>
public void PlayOneShot(AudioClip clip)
{
m_GameObject.name = clip.name;
m_AudioSource.PlayOneShot(clip);
CoroutineUtility.WaitForSeconds(clip.length, Release);
}

/// <summary>
/// Release pooled sound.
/// </summary>
public void Release()
{
OnRelease?.Invoke();
}

internal void Deactivate()
{
m_GameObject.SetActive(false);
m_AudioSource.volume = 1;
m_AudioSource.clip = null;
}

internal void Activate()
{
m_GameObject.SetActive(true);
}
}
}
3 changes: 3 additions & 0 deletions Runtime/Sound/PooledAudioSource.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions Samples.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions Samples/AudioCenter.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

29 changes: 29 additions & 0 deletions Samples/AudioCenter/AudioCenterSample.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using StansAssets.Foundation.Audio;
using UnityEngine;
using UnityEngine.UI;

namespace StansAssets.Foundation.Samples
{
class AudioCenterSample : MonoBehaviour
{
[SerializeField]
AudioClip m_TestClip;

[SerializeField]
AudioListener m_AudioListener;

[SerializeField]
Button m_PlayButton;

AudioCenter m_AudioCenter;

void Start()
{
m_AudioCenter = new AudioCenter("Sample Audio Center", m_AudioListener);
m_PlayButton.onClick.AddListener(() =>
{
m_AudioCenter.PlayOneShot(m_TestClip);
});
}
}
}
11 changes: 11 additions & 0 deletions Samples/AudioCenter/AudioCenterSample.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 25e5c5d

Please sign in to comment.