Unity——音频管理器(附例子)
在实际游戏开发中,音效既是一个相对独立的部分,又与其他游戏逻辑密切关联。也就是说,与音效相关的代码会插入很多细节代码中。
而且在音效非常丰富的情况下,如果每一个游戏模块都单独播放音效,那么可能会带来一些问题。例如,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.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;}//遍历所有频道,如果有频道空闲直接播放新音频,并退出//如果没有空闲频道,先找到最开始播放的频道(oldest),稍后使用int oldest = -1;float time = 10000000.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.pitch=pitch;m_channels[i].channel.panStereo=pan;m_channels[i].channel.loop = false;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.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游戏中,需要考虑音效播放的空间位置(目的是营造真实感),这是统一创建音源就不是很合适了
相关文章:
Unity——音频管理器(附例子)
在实际游戏开发中,音效既是一个相对独立的部分,又与其他游戏逻辑密切关联。也就是说,与音效相关的代码会插入很多细节代码中。 而且在音效非常丰富的情况下,如果每一个游戏模块都单独播放音效,那么可能会带来一些问题…...
TCP协议基础
一: TCP协议是什么? TCP协议是基于面向连接,可靠传输,基于字节流的传输层通信协议 1. 面向连接 TCP协议是一种面向连接的协议,意味着在双方在建立数据传输之前,需要进行一个逻辑上的连接,且是…...
C# NetTopologySuite+ProjNet 任意图形类型坐标转换
添加引用:NetTopologySuite、ProjNet、ProjNet.SRID Program.cs文件: using ProjNet.CoordinateSystems; using ProjNet.CoordinateSystems.Transformations; using ProjNet.SRID; using System; using System.Collections.Generic; using System.Linq;…...
Windows笔记本电脑开机黑屏
Windows笔记本电脑开机黑屏 最近,我遇到了一件奇怪的事情。我的Windows笔记本电脑在开机时出现了一个黑屏,没有任何反应。我尝试了多种方法,包括重启和恢复出厂设置,但都无济于事。 我开始感到担心,因为这只会影响到…...
Samb共享用户的设置和修改Linux用户的id号,修改Linux组的id号,加入组,删除组成员等
零、samba帐号的设置 为samba共享添加用户,并设定仅能由授权用户进入的共享 #增加没有家目录,也无法登录系统的空用户 useradd -M userA -s /sbin/nologin #-M 选项是--no-create-home的简写形式,即不为该用户配置家目录;-s选项&…...
VBA:对Excel单元格进行合并操作
Sub hb()Dim nn 3For i 3 To 18If Range("b" & i) <> Range("b" & i 1) ThenRange("b" & n & ":b" & i).Mergen i 1End IfNextEnd Sub...
HTML5离线储存
简介 离线存储指的是:在用户没有与因特网连接时,可以正常访问站点或应用,在用户与因特网连接时,更新用户机器上的缓存文件。 原理:HTML5的离线存储是基于一个新建的 .appcache 文件的缓存机制(不是存储技术)…...
cmd: Union[List[str], str], ^ SyntaxError: invalid syntax
跑项目在调用from easyprocess import EasyProcess 遇到报错: cmd: Union[List[str], str], ^ SyntaxError: invalid syntax猜测是EasyProcess版本与python版本不对应 pip show EasyProcess查证一下: WARNING: pip is being invoked by an old…...
2023高教社杯数学建模思路 - 案例:异常检测
文章目录 赛题思路一、简介 -- 关于异常检测异常检测监督学习 二、异常检测算法2. 箱线图分析3. 基于距离/密度4. 基于划分思想 建模资料 赛题思路 (赛题出来以后第一时间在CSDN分享) https://blog.csdn.net/dc_sinor?typeblog 一、简介 – 关于异常…...
FFDNet-pytorch版本代码测试教程
一、FFDNet-pytorch版本代码下载 (1)FFDNet-pytorch下载 https://download.csdn.net/download/qq_41104871/88233742 二、FFDNet-pytorch版本代码运行环境配置 (1)FFDNet-pytorch版本代码运行环境配置 https://blog.csdn.net/q…...
uni-app项目由hbuilder项目转化为cli项目
1.背景 原uni-app项目是通过hbuilder创建的,运行以及打包都要依赖于hbuilder运行;一般在vscode开发,在hbuilder运行比较怪异;后续希望脱离hbuilder运行并能通过构建平台进行打包,因此将hbuilder项目转化为cli项目 2.…...
使用SpaceDesk连接平板作为电脑副屏详细步骤教程
文章目录 下载安装PC端安装安卓端安装 配置步骤PC端安卓端 连接 SpaceDesk官网链接https://www.spacedesk.net/ (应该是需要科学上网才能进入) SpaceDesk它可以连接安卓,苹果的平板,手机等,也可以连接其他可以打开网页(HTML5)的设备。 这里我…...
云备份——第三方库使用介绍(下)
httplib库,一个C11单文件头的跨平台HTTP/HTTPS库。安装起来非常容易。只需包含httplib.h在你的代码中即可。 httplib库实际上是用于搭建一个简单的http服务器或者客户端的库,这种第三方网络库,可以让我们免去搭建服务器或客户端的时间&#x…...
springboot实战(一)之项目搭建
环境准备 ideajdk1.8springboot版本 2.7.15 项目开始 1.打开idea,点击new project 2.选择spring initillizr 核对:Server Url是否是:start.spring.io,然后根据自己依次设置项目名称、存储位置和包名,如下ÿ…...
线性代数的学习和整理16:什么是各种空间(类型),向量空间,距离(类型)?
目录 1 空间相关的群,环,域,集合,空间的预备知识 1.1:群,环,域,集合,空间的定义(表示不懂,只是做个标记) 2 空间 2.1 各种空间概念…...
css实现文字翻转效果
csss实现文字翻转效果 主要实现核心属性 direction: rtl; unicode-bidi: bidi-override; direction: rtl; 这个属性用于指定文本的方向为从右到左(Right-to-Left)。它常用于处理阿拉伯语、希伯来语等从右向左书写的文字样式。当设置了 direction: rtl; …...
19 Linux之Python定制篇-apt软件管理和远程登录
19 Linux之Python定制篇-apt软件管理和远程登录 文章目录 19 Linux之Python定制篇-apt软件管理和远程登录19.1 apt软件管理19.1.1 apt介绍19.1.2 更新软件下载地址-阿里源19.1.3 使用apt完成安装和卸载vim 19.2 远程登录Ubuntu 学习视频来自于B站【小白入门 通俗易懂】2021韩顺…...
WebDAV之π-Disk派盘 + notototo
notototo是一款功能丰富的笔记软件,提供了多种功能,包括载入PDF文件并进行批注和标记的能力。您可以使用Apple Pencil或手指在PDF文件上进行写作和绘图操作。 同时,notototo也提供了与团队合作的功能,您可以连接到服务器并与他人协作。此外,您还可以在notototo中进行绘图,…...
_kbhit() and getch() 在小游戏中用不了。因为控制台函数,仅在控制台程序中可用
太长不看版: _kbhit() and getch() 包含在conio.h中。 conio是Console Input/Output(控制台输入输出)的简写,其中定义了通过控制台进行数据输入和数据输出的函数,主要是一些用户通过按键盘产生的对应操作,…...
dayjs格式转换成日期
目录 方法一: 编辑方法二: 这个项目在筛选订单时间的时候是由前端进行筛选的,用的是adt-design-pro进行二开的,其中在用日期组件的时候遇到了一个问题,组件返回的是: 但是我需要的是年-月-日ÿ…...
Linux打印机驱动foo2zjs全攻略:从安装到优化的完整指南
Linux打印机驱动foo2zjs全攻略:从安装到优化的完整指南 【免费下载链接】foo2zjs A linux printer driver for QPDL protocol - copy of http://foo2zjs.rkkda.com/ 项目地址: https://gitcode.com/gh_mirrors/fo/foo2zjs 价值定位:解决Linux打印…...
PyTorch张量操作实战:从基础运算到CNN应用
1. PyTorch张量基础:从概念到创建 第一次接触PyTorch张量时,我完全被各种术语搞晕了。什么标量、向量、矩阵,还有这个奇怪的"张量"词。后来才发现,其实张量就是多维数组的另一种说法,只不过在深度学习中我们…...
VSCode里装个Cline,真能让写代码快10倍?我的真实体验和避坑指南
VSCode里装个Cline,真能让写代码快10倍?我的真实体验和避坑指南 第一次听说Cline这个VSCode插件时,我内心是充满怀疑的。作为一个在代码堆里摸爬滚打多年的开发者,早已对各种"革命性"工具免疫。但当我看到同行在短短十分…...
告别“直升机起飞”:用4张RTX 4090 DIY一台能放在工位旁的静音深度学习工作站
告别“直升机起飞”:用4张RTX 4090 DIY一台能放在工位旁的静音深度学习工作站 在深度学习研究的前沿领域,算力需求与日俱增,但商业级服务器的高昂价格和庞大体积往往让个人研究者望而却步。更令人困扰的是,传统多GPU工作站在满载…...
Qwen3.5-9B镜像免配置实战:Docker化迁移与端口映射最佳实践
Qwen3.5-9B镜像免配置实战:Docker化迁移与端口映射最佳实践 1. 项目概述 Qwen3.5-9B是一个拥有90亿参数的开源大语言模型,具备强大的逻辑推理、代码生成和多轮对话能力。该模型支持多模态理解(图文输入)和长上下文处理ÿ…...
别再只改yaml了!深入理解YOLOv5检测头:从P2到P5,如何根据你的目标大小选择最优组合?
深入解析YOLOv5多尺度检测头:从理论到实践的选择艺术 在计算机视觉领域,目标检测一直是核心任务之一。YOLO系列算法以其高效的检测速度和良好的精度表现,成为工业界和学术界的热门选择。然而,很多开发者在使用YOLOv5时,…...
ICLR 2026 | 告别Top-K检索!RF-Mem在嵌入空间逐步重构证据链,实现长记忆渐进式唤醒
今天分享一篇来自大连理工大学、香港城市大学、华为和中国科学技术大学的最新工作 RF-Mem,发表于ICLR 2026。这篇工作关注个性化大模型中的一个关键问题:当用户历史越来越长时,模型到底该怎样从海量记忆里,准确找回“此时此刻最相…...
WSL2下USB串口设备‘失踪’?手把手教你找回/dev/ttyUSB0(以Quectel模块为例)
WSL2下USB串口设备消失的终极解决方案:从原理到实战 最近在WSL2环境下调试Quectel模块时,发现一个奇怪现象:lsusb明明能识别设备,但/dev/ttyUSB0却神秘失踪。这让我想起去年调试树莓派时遇到的类似问题,但WSL2的环境特…...
NVIDIA Profile Inspector 终极指南:免费解锁显卡隐藏性能的完整教程
NVIDIA Profile Inspector 终极指南:免费解锁显卡隐藏性能的完整教程 【免费下载链接】nvidiaProfileInspector 项目地址: https://gitcode.com/gh_mirrors/nv/nvidiaProfileInspector 想要让游戏画面更流畅、画质更清晰吗?NVIDIA Profile Inspe…...
HumanoidVerse深度解析:如何通过多模拟器框架实现人形机器人sim2real高效训练
1. HumanoidVerse框架概览:多模拟器支持与模块化设计 HumanoidVerse是卡耐基梅隆大学(CMU)推出的开源框架,专门针对人形机器人的sim2real训练需求。这个框架最大的特点在于其多模拟器支持架构,能够无缝对接IsaacGym、IsaacSim和Genesis三种主…...
