版权声明:本文为博主原创文章,转载请注明出处。 https://blog.csdn.net/qq_34937637/article/details/82585486
unity游戏制作时,经常需要播放音效,如果没有一个音效管理类,随时随地都可以播放音乐,不利于代码的管理。我们可以将所有关于音效集中到一个管理类当中,可以将这个音效管理器写成单例,也可以将它当作一个模块,和项目的其他模块通信。
以下提供了两种音效管理器的代码(可根据需求自己添加API或进行代码重构):
using UnityEngine;
/// <summary>
/// 音效管理channel
/// </summary>
public class AudioChannels : MonoBehaviour {
private const int AUDIO_CHANNEL_NUM = 8;
private struct CHANNEL {
public AudioSource channel;
public float keyOnTime;
};
private CHANNEL[] m_channels;
void Awake () {
m_channels = new CHANNEL[AUDIO_CHANNEL_NUM];
for (int i = 0; i < AUDIO_CHANNEL_NUM; i++) {
m_channels[i].channel = gameObject.AddComponent<AudioSource>();
m_channels[i].keyOnTime = 0;
}
}
public int PlayOneShot(AudioClip clip,float volume ,float pan ,float pitch = 1.0f)
{
for (int i = 0; i < m_channels.Length ; i++) {
if (m_channels[i].channel.isPlaying &&
m_channels[i].channel.clip == clip &&
m_channels[i].keyOnTime >= Time.time - 0.03f)
return -1;
}
int oldest = -1;
float time = 1000000000.0f;
for (int i = 0; i < m_channels.Length ; i++) {
if (m_channels[i].channel.loop == false &&
m_channels[i].channel.isPlaying &&
m_channels[i].keyOnTime < time) {
oldest = i;
time = m_channels[i].keyOnTime;
}
if (!m_channels[i].channel.isPlaying) {
m_channels[i].channel.clip = clip;
m_channels[i].channel.volume = volume;
m_channels[i].channel.panStereo = pan;
m_channels[i].channel.loop = false;
m_channels[i].channel.pitch = pitch;
m_channels[i].channel.Play();
m_channels[i].keyOnTime = Time.time;
return i;
}
}
// 频道没有打开的情况
if (oldest >= 0) {
m_channels[oldest].channel.clip = clip;
m_channels[oldest].channel.volume = volume;
m_channels[oldest].channel.panStereo = pan;
m_channels[oldest].channel.loop = false;
m_channels[oldest].channel.pitch = pitch;
m_channels[oldest].channel.Play();
m_channels[oldest].keyOnTime = Time.time;
return oldest;
}
return -1;
}
public int PlayLoop(AudioClip clip,float volume ,float pan,float pitch = 1.0f )
{
for (int i = 0; i < m_channels.Length ; i++) {
if (!m_channels[i].channel.isPlaying) {
m_channels[i].channel.clip = clip;
m_channels[i].channel.volume = volume;
m_channels[i].channel.panStereo = pan;
m_channels[i].channel.loop = true;
m_channels[i].channel.pitch = pitch;
m_channels[i].channel.Play();
m_channels[i].keyOnTime = Time.time;
return i;
}
}
return -1;
}
public void StopAll()
{
foreach(CHANNEL channel in m_channels)
channel.channel.Stop();
}
public void Stop(int id)
{
if ( id >= 0 && id < m_channels.Length ) {
m_channels[id].channel.Stop();
}
}
}
第二种:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class AudioManager : BaseManager {
public AudioManager(GameFacade facade) : base(facade) { }
private const string Sound_Prefix = "Sounds/";
public const string Sound_Alert = "Alert";
public const string Sound_ArrowShoot = "ArrowShoot";
public const string Sound_Bg_Fast = "Bg(fast)";
public const string Sound_Bg_Moderate = "Bg(moderate)";
public const string Sound_ButtonClick = "ButtonClick";
public const string Sound_Miss = "Miss";
public const string Sound_ShootPerson = "ShootPerson";
public const string Sound_Timer = "Timer";
private AudioSource bgAudioSource;
private AudioSource normalAudioSource;
public override void OnInit()
{
GameObject audioSourceGO = new GameObject("AudioSource(GameObject)");
bgAudioSource = audioSourceGO.AddComponent<AudioSource>();
normalAudioSource = audioSourceGO.AddComponent<AudioSource>();
PlaySound(bgAudioSource, LoadSound(Sound_Bg_Moderate),0.5f, true);
}
public void PlayBgSound(string soundName)
{
PlaySound(bgAudioSource, LoadSound(soundName), 0.5f, true);
}
public void PlayNormalSound(string soundName)
{
PlaySound(normalAudioSource, LoadSound(soundName), 1f);
}
private void PlaySound( AudioSource audioSource,AudioClip clip,float volume, bool loop=false)
{
audioSource.clip = clip;
audioSource.volume = volume;
audioSource.loop = loop;
audioSource.Play();
}
private AudioClip LoadSound(string soundsName)
{
return Resources.Load<AudioClip>(Sound_Prefix + soundsName);
}
}