网站建设 开发 模板,微信小程序公众平台官网,可以上传软件的网站,老网站做成适合手机端的网站怎么做在实际游戏开发中#xff0c;音效既是一个相对独立的部分#xff0c;又与其他游戏逻辑密切关联。也就是说#xff0c;与音效相关的代码会插入很多细节代码中。
而且在音效非常丰富的情况下#xff0c;如果每一个游戏模块都单独播放音效#xff0c;那么可能会带来一些问题…在实际游戏开发中音效既是一个相对独立的部分又与其他游戏逻辑密切关联。也就是说与音效相关的代码会插入很多细节代码中。
而且在音效非常丰富的情况下如果每一个游戏模块都单独播放音效那么可能会带来一些问题。例如Audio Source组件很多但大部分限制同时播放的音效太多会显得混乱。
成熟的技术开发思路是如果音效不多、没有造成问题则完全可以简单处理如果音效已经引起了代码的混乱和性能问题就有必要统一管理所有的音源和音效也就是设计一个易用的音频管理器。有了音频管理器所有的Audio Source组件都会统一创建而所有音效播放的需求都要通过调用音频管理器的方法简介实现。
音频管理器有很多设计思路其中一种比较简洁的思路是事先指定游戏中最多同时播放多少个音频然后创建若干个音源。例如最多播放8个音频那么就创建8个Audio Source组件这8个组件可以看作8个频道。需要播放音频时只要找到任意一个空闲的频道播放即可而如果8个频道都正在播放那么就可以用某种策略替换音频如将播放时间最早的音频替换成新的音频。用这种简单的思路创建音频管理器的代码如下
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//音频管理器
public class AudioManager : 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.AddComponentAudioSource();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;}//遍历所有频道如果有频道空闲直接播放新音频并退出//如果没有空闲频道先找到最开始播放的频道oldest稍后使用int oldest -1;float time 10000000.0f;for (int i 0; i m_channels.Length; i){if (m_channels[i].channel.loopfalse m_channels[i].channel.isPlaying m_channels[i].keyOnTime time){oldest i;timem_channels[i].keyOnTime;}if (!m_channels[i].channel.isPlaying){m_channels[i].channel.clipclip;m_channels[i].channel.volumevolume;m_channels[i].channel.pitchpitch;m_channels[i].channel.panStereopan;m_channels[i].channel.loop false;m_channels[i].channel.Play();m_channels[i].keyOnTime Time.time;return i;}}//运行到这里说明没有空闲频道。让新的音频顶替最早播出的音频if(oldest0){m_channels[oldest].channel.clip clip;m_channels[oldest].channel.volume volume;m_channels[oldest].channel.pitch pitch;m_channels[oldest].channel.panStereo pan;m_channels[oldest].channel.loop false;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.pitch pitch;m_channels[i].channel.panStereo pan;m_channels[i].channel.loop true;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();}//公开方法根据频道ID停止音频public void Stop(int id){if (id 0 id m_channels.Length){m_channels[id].channel.Stop();}}
}以上代码可以作为创建音频管理器的一种思路参考。
实际上根据游戏类型的不同音频管理器的创建思路也有区别。例如在很多3D游戏中需要考虑音效播放的空间位置目的是营造真实感这是统一创建音源就不是很合适了