这篇文章主要为大家详细介绍了如何通过Unity实现高效的音效管理类,文中的示例代码讲解详细,具有一定的借鉴价值,感兴趣的可以了解一下
效果
自动维护一个 AudioSource的池子
如果超过了池子的峰值 池子会生成一个新的AudioSource对象来进行扩容
- 支持2D音效调用方式 public void PlaySound( string url, float volume = 1.0f, bool loop = false )
- 支持2D音乐调用方式 public void PlayMusic( string url, float volume = 1.0f, bool loop = true )
- 支持3D音效调用方式 public void PlaySoundAtPoint( string url, Vector3 position, float volume = 1f )
食用方式
更改这块的加载 用你们自己框架里的加载方式 或者 走 Resource.Load
源码
using ResourceFramework;
using System.Collections.Generic;
using UnityEngine;
public class AudioManager : SingleTon<AudioManager>
{
Queue<AudioSource> freeAudioSources = new Queue<AudioSource>();
List<AudioSource> activeAudioSources = new List<AudioSource>();
Dictionary<string, List<AudioSource>> playingSources = new Dictionary<string, List<AudioSource>>();
List<AudioSource> musicSources = new List<AudioSource>();
List<AudioSource> soundSources = new List<AudioSource>();
Dictionary<string, AudioClip> audioClips = new Dictionary<string, AudioClip>();
Transform transform;
public float soundVolume { private set; get; } = 1.0f;
public float musicVolume { private set; get; } = 1.0f;
public bool soundMute { private set; get; } = false;
public bool musicMute { private set; get; } = false;
/// <summary>
/// 初始化 给音效节点们一个爸爸
/// </summary>
/// <param name="root"></param>
public void Init( Transform root )
{
transform = root;
LoadAudioClip();//默认音效加载
}
/// <summary>
/// 加载本地音效到音效缓存池
/// </summary>
/// <param name="url"></param>
public void LoadAudioClip( string url = "Assets/AssetBundle/Sounds" )
{
AudioClip[] clips = null;
//#if UNITY_EDITOR
// var files = System.IO.Directory.GetFiles( url );
// var clipList = new List<AudioClip>();
// foreach ( var file in files )
// {
// var ac = UnityEditor.AssetDatabase.LoadAssetAtPath<AudioClip>( file );
// if ( null != ac )
// {
// clipList.Add( ac );
// }
// }
// clips = clipList.ToArray();
//#else
List<AudioClip> clipList = new List<AudioClip>();
for ( int i = 0; i < AllSoundName.allSoundPath.Length; i++ )
{
clipList.Add( Loader.LoadAsset<AudioClip>( $"{url}/{AllSoundName.allSoundPath[ i ]}.mp3" ) );
}
clips = clipList.ToArray();
//#endif
foreach ( var clip in clips )
{
audioClips.Add( clip.name, clip );
}
}
/// <summary>
/// 缓存一个音效到池子里
/// </summary>
/// <param name="audioClip"></param>
public void Cache( AudioClip audioClip )
{
if ( !audioClips.ContainsKey( audioClip.name ) )
{
audioClips.Add( audioClip.name, audioClip );
}
}
/// <summary>
/// 需要主动去调用这个更新检查 当然你也可以开一个定时器来检测
/// </summary>
public void OnUpdate()
{
for ( int i = 0; i < activeAudioSources.Count; i++ )
{
if ( !activeAudioSources[ i ].isPlaying )
{
var free = activeAudioSources[ i ];
free.gameObject.SetActive( false );
freeAudioSources.Enqueue( free );
activeAudioSources.RemoveAt( i-- );
soundSources.Remove( free );
musicSources.Remove( free );
}
}
}
/// <summary>
/// 设置 音效系统音量 0~1
/// </summary>
/// <param name="volume"></param>
public void SetSoundSysVolume( float volume )
{
float newVolume = Mathf.Clamp( volume, 0, 1 );
float scale = newVolume / soundVolume;
soundVolume = newVolume;
foreach ( var asource in soundSources )
{
asource.volume *= scale;
}
}
/// <summary>
/// 设置 音乐系统音量 0~1
/// </summary>
/// <param name="volume"></param>
public void SetMusicSysVolume( float volume )
{
float newVolume = Mathf.Clamp( volume, 0, 1 );
float scale = newVolume / musicVolume;
musicVolume = newVolume;
foreach ( var asource in musicSources )
{
asource.volume *= scale;
}
}
/// <summary>
/// 设置音效静音状态
/// </summary>
/// <param name="isMute"></param>
public void SetSoundMuteState( bool isMute )
{
soundMute = isMute;
foreach ( var asource in soundSources )
{
asource.mute = soundMute;
}
}
/// <summary>
/// 设置音乐静音状态
/// </summary>
/// <param name="isMute"></param>
public void SetMusicMuteState( bool isMute )
{
musicMute = isMute;
foreach ( var asource in musicSources )
{
asource.mute = musicMute;
}
}
/// <summary>
/// 播放音乐 默认循环播放
/// </summary>
/// <param name="url"></param>
/// <param name="volume"></param>
/// <param name="loop"></param>
public void PlayMusic( string url, float volume = 1.0f, bool loop = true )
{
if ( freeAudioSources.Count == 0 )
{
GenAudioSouceNew();
}
var audioSource = freeAudioSources.Dequeue();
activeAudioSources.Add( audioSource );
Recoverd( url, audioSource );
audioSource.gameObject.SetActive( true );
audioSource.volume = volume * musicVolume;
audioSource.mute = soundMute;
audioSource.loop = loop;
audioSource.spatialBlend = 0f;
audioSource.clip = GetAudioClip( url );
audioSource.Play();
if ( soundSources.Contains( audioSource ) )
{
soundSources.Remove( audioSource );
}
if ( !musicSources.Contains( audioSource ) )
{
musicSources.Add( audioSource );
}
}
/// <summary>
/// 停掉所有url相关的音效
/// 因为是可以同时存在多个相同url的音效的 它们都有自己的生命周期
/// </summary>
/// <param name="url"></param>
public void StopMusic( string url )
{
if ( playingSources.ContainsKey( url ) )
{
playingSources[ url ].ForEach( s => s.Stop() );
playingSources.Remove( url );
}
}
/// <summary>
/// 播放音效 默认单次播放
/// </summary>
/// <param name="url"></param>
/// <param name="volume"></param>
/// <param name="loop"></param>
public void PlaySound( string url, float volume = 1.0f, bool loop = false )
{
if ( freeAudioSources.Count == 0 )
{
GenAudioSouceNew();
}
var audioSource = freeAudioSources.Dequeue();
activeAudioSources.Add( audioSource );
Recoverd( url, audioSource );
audioSource.gameObject.SetActive( true );
audioSource.volume = volume * soundVolume;
audioSource.mute = soundMute;
audioSource.loop = loop;
audioSource.spatialBlend = 0f;
audioSource.clip = GetAudioClip( url );
audioSource.Play();
if ( musicSources.Contains( audioSource ) )
{
musicSources.Remove( audioSource );
}
if ( !soundSources.Contains( audioSource ) )
{
soundSources.Add( audioSource );
}
}
/// <summary>
/// 3D世界播放一个音效 指定一个位置
/// </summary>
/// <param name="url"></param>
/// <param name="position"></param>
/// <param name="volume"></param>
public void PlaySoundAtPoint( string url, Vector3 position, float volume = 1f )
{
if ( freeAudioSources.Count == 0 )
{
GenAudioSouceNew();
}
var audioSource = freeAudioSources.Dequeue();
activeAudioSources.Add( audioSource );
Recoverd( url, audioSource );
audioSource.gameObject.transform.position = position;
audioSource.gameObject.SetActive( true );
audioSource.clip = GetAudioClip( url );
audioSource.volume = volume * soundVolume;
audioSource.mute = soundMute;
audioSource.loop = false;
audioSource.spatialBlend = 1f;
audioSource.Play();
}
public void PlayClipAtPoint( AudioClip clip, Vector3 position, float volume = 1f )
{
foreach ( var item in audioClips )
{
if ( item.Value == clip )
{
PlaySoundAtPoint( item.Key, position, volume );
break;
}
}
}
public AudioClip GetAudioClip( string url )
{
AudioClip clip = null;
if ( audioClips.TryGetValue( url, out clip ) )
{
return clip;
}
return null;
}
private void GenAudioSouceNew()
{
var obj = new GameObject( $"AudioComponent_{( activeAudioSources.Count + freeAudioSources.Count )}" );
obj.transform.SetParent( transform, true );
var asource = obj.AddComponent<AudioSource>();
asource.loop = false;
asource.volume = 0;
asource.playOnAwake = false;
asource.mute = false;
freeAudioSources.Enqueue( asource );
}
private void Recoverd( string url, AudioSource ac )
{
List<AudioSource> result = null;
if ( !playingSources.TryGetValue( url, out result ) )
{
result = new List<AudioSource>();
playingSources.Add( url, result );
}
result.Add( ac );
}
}
以上就是Unity实现高效的音效管理类的示例代码的详细内容,更多关于Unity音效管理类的资料请关注织梦云其它相关文章!
沃梦达教程
本文标题为:Unity实现高效的音效管理类的示例代码
基础教程推荐
猜你喜欢
- ZooKeeper的安装及部署教程 2023-01-22
- C# windows语音识别与朗读实例 2023-04-27
- C#控制台实现飞行棋小游戏 2023-04-22
- C#类和结构详解 2023-05-30
- C# List实现行转列的通用方案 2022-11-02
- unity实现动态排行榜 2023-04-27
- 一个读写csv文件的C#类 2022-11-06
- winform把Office转成PDF文件 2023-06-14
- linux – 如何在Debian Jessie中安装dotnet core sdk 2023-09-26
- C# 调用WebService的方法 2023-03-09