当前位置: 首页 > news >正文

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——音频管理器(附例子)

在实际游戏开发中&#xff0c;音效既是一个相对独立的部分&#xff0c;又与其他游戏逻辑密切关联。也就是说&#xff0c;与音效相关的代码会插入很多细节代码中。 而且在音效非常丰富的情况下&#xff0c;如果每一个游戏模块都单独播放音效&#xff0c;那么可能会带来一些问题…...

TCP协议基础

一&#xff1a; TCP协议是什么&#xff1f; TCP协议是基于面向连接&#xff0c;可靠传输&#xff0c;基于字节流的传输层通信协议 1. 面向连接 TCP协议是一种面向连接的协议&#xff0c;意味着在双方在建立数据传输之前&#xff0c;需要进行一个逻辑上的连接&#xff0c;且是…...

C# NetTopologySuite+ProjNet 任意图形类型坐标转换

添加引用&#xff1a;NetTopologySuite、ProjNet、ProjNet.SRID Program.cs文件&#xff1a; using ProjNet.CoordinateSystems; using ProjNet.CoordinateSystems.Transformations; using ProjNet.SRID; using System; using System.Collections.Generic; using System.Linq;…...

Windows笔记本电脑开机黑屏

Windows笔记本电脑开机黑屏 最近&#xff0c;我遇到了一件奇怪的事情。我的Windows笔记本电脑在开机时出现了一个黑屏&#xff0c;没有任何反应。我尝试了多种方法&#xff0c;包括重启和恢复出厂设置&#xff0c;但都无济于事。 我开始感到担心&#xff0c;因为这只会影响到…...

Samb共享用户的设置和修改Linux用户的id号,修改Linux组的id号,加入组,删除组成员等

零、samba帐号的设置 为samba共享添加用户&#xff0c;并设定仅能由授权用户进入的共享 #增加没有家目录&#xff0c;也无法登录系统的空用户 useradd -M userA -s /sbin/nologin #-M 选项是--no-create-home的简写形式&#xff0c;即不为该用户配置家目录&#xff1b;-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离线储存

简介 离线存储指的是&#xff1a;在用户没有与因特网连接时&#xff0c;可以正常访问站点或应用&#xff0c;在用户与因特网连接时&#xff0c;更新用户机器上的缓存文件。 原理&#xff1a;HTML5的离线存储是基于一个新建的 .appcache 文件的缓存机制(不是存储技术)&#xf…...

cmd: Union[List[str], str], ^ SyntaxError: invalid syntax

跑项目在调用from easyprocess import EasyProcess 遇到报错&#xff1a; cmd: Union[List[str], str], ^ SyntaxError: invalid syntax猜测是EasyProcess版本与python版本不对应 pip show EasyProcess查证一下&#xff1a; WARNING: pip is being invoked by an old…...

2023高教社杯数学建模思路 - 案例:异常检测

文章目录 赛题思路一、简介 -- 关于异常检测异常检测监督学习 二、异常检测算法2. 箱线图分析3. 基于距离/密度4. 基于划分思想 建模资料 赛题思路 &#xff08;赛题出来以后第一时间在CSDN分享&#xff09; https://blog.csdn.net/dc_sinor?typeblog 一、简介 – 关于异常…...

FFDNet-pytorch版本代码测试教程

一、FFDNet-pytorch版本代码下载 &#xff08;1&#xff09;FFDNet-pytorch下载 https://download.csdn.net/download/qq_41104871/88233742 二、FFDNet-pytorch版本代码运行环境配置 &#xff08;1&#xff09;FFDNet-pytorch版本代码运行环境配置 https://blog.csdn.net/q…...

uni-app项目由hbuilder项目转化为cli项目

1.背景 原uni-app项目是通过hbuilder创建的&#xff0c;运行以及打包都要依赖于hbuilder运行&#xff1b;一般在vscode开发&#xff0c;在hbuilder运行比较怪异&#xff1b;后续希望脱离hbuilder运行并能通过构建平台进行打包&#xff0c;因此将hbuilder项目转化为cli项目 2.…...

使用SpaceDesk连接平板作为电脑副屏详细步骤教程

文章目录 下载安装PC端安装安卓端安装 配置步骤PC端安卓端 连接 SpaceDesk官网链接https://www.spacedesk.net/ (应该是需要科学上网才能进入) SpaceDesk它可以连接安卓,苹果的平板,手机等&#xff0c;也可以连接其他可以打开网页&#xff08;HTML5&#xff09;的设备。 这里我…...

云备份——第三方库使用介绍(下)

httplib库&#xff0c;一个C11单文件头的跨平台HTTP/HTTPS库。安装起来非常容易。只需包含httplib.h在你的代码中即可。 httplib库实际上是用于搭建一个简单的http服务器或者客户端的库&#xff0c;这种第三方网络库&#xff0c;可以让我们免去搭建服务器或客户端的时间&#x…...

springboot实战(一)之项目搭建

环境准备 ideajdk1.8springboot版本 2.7.15 项目开始 1.打开idea&#xff0c;点击new project 2.选择spring initillizr 核对&#xff1a;Server Url是否是&#xff1a;start.spring.io&#xff0c;然后根据自己依次设置项目名称、存储位置和包名&#xff0c;如下&#xff…...

线性代数的学习和整理16:什么是各种空间(类型),向量空间,距离(类型)?

目录 1 空间相关的群&#xff0c;环&#xff0c;域&#xff0c;集合&#xff0c;空间的预备知识 1.1&#xff1a;群&#xff0c;环&#xff0c;域&#xff0c;集合&#xff0c;空间的定义&#xff08;表示不懂&#xff0c;只是做个标记&#xff09; 2 空间 2.1 各种空间概念…...

css实现文字翻转效果

csss实现文字翻转效果 主要实现核心属性 direction: rtl; unicode-bidi: bidi-override; direction: rtl; 这个属性用于指定文本的方向为从右到左&#xff08;Right-to-Left&#xff09;。它常用于处理阿拉伯语、希伯来语等从右向左书写的文字样式。当设置了 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() 在小游戏中用不了。因为控制台函数,仅在控制台程序中可用

太长不看版&#xff1a; _kbhit() and getch() 包含在conio.h中。 conio是Console Input/Output&#xff08;控制台输入输出&#xff09;的简写&#xff0c;其中定义了通过控制台进行数据输入和数据输出的函数&#xff0c;主要是一些用户通过按键盘产生的对应操作&#xff0c…...

dayjs格式转换成日期

目录 方法一&#xff1a; ​编辑方法二&#xff1a; 这个项目在筛选订单时间的时候是由前端进行筛选的&#xff0c;用的是adt-design-pro进行二开的&#xff0c;其中在用日期组件的时候遇到了一个问题&#xff0c;组件返回的是&#xff1a; 但是我需要的是年-月-日&#xff…...

终极免费解锁Cursor Pro高级功能:完整解决方案深度解析

终极免费解锁Cursor Pro高级功能&#xff1a;完整解决方案深度解析 【免费下载链接】cursor-free-vip [Support 0.45]&#xff08;Multi Language 多语言&#xff09;自动注册 Cursor Ai &#xff0c;自动重置机器ID &#xff0c; 免费升级使用Pro 功能: Youve reached your tr…...

5步快速上手OmenSuperHub:彻底掌控暗影精灵性能的终极指南

5步快速上手OmenSuperHub&#xff1a;彻底掌控暗影精灵性能的终极指南 【免费下载链接】OmenSuperHub 使用 WMI BIOS控制性能和风扇速度&#xff0c;自动解除DB功耗限制。 项目地址: https://gitcode.com/gh_mirrors/om/OmenSuperHub 你是否对官方Omen Gaming Hub的臃肿…...

Cursor Pro免费激活终极指南:简单快速解锁AI编程高级功能

Cursor Pro免费激活终极指南&#xff1a;简单快速解锁AI编程高级功能 【免费下载链接】cursor-free-vip [Support 0.45]&#xff08;Multi Language 多语言&#xff09;自动注册 Cursor Ai &#xff0c;自动重置机器ID &#xff0c; 免费升级使用Pro 功能: Youve reached your …...

从ChatGLM2到LLaMA2:大厂如何用GQA和MQA在推理速度与模型质量间做取舍?

大模型注意力机制实战&#xff1a;GQA与MQA如何重塑推理效率与生成质量的平衡 当ChatGLM2-6B在推理速度上展现出惊人优势时&#xff0c;技术团队发现其生成质量偶尔会出现波动&#xff1b;而LLaMA2虽然保持了稳定的输出品质&#xff0c;却在资源消耗上让不少企业望而却步。这背…...

【普中 51-Ai8051 开发攻略】-- 第 30 章 OLED 液晶显示实验-硬件 IIC

(1)实验平台&#xff1a; 普中 51-Ai8051 开发板​​https://item.taobao.com/item.htm?abbucket17&id1026052331067(2)资料下载 &#xff1a;普中科技-各型号产品资料下载链接 前面已经使用 IO 口软件模拟 IIC 时序与 OLED 通信实现字符汉字的显示。 本章学习使用 AI805…...

【Perplexity健身计划搜索实战指南】:20年AI搜索专家亲授3大精准检索心法,错过再等一年

更多请点击&#xff1a; https://codechina.net 第一章&#xff1a;Perplexity健身计划搜索实战指南导论 Perplexity 是一款以推理深度和引用可追溯性见长的 AI 搜索工具&#xff0c;特别适合需要结构化、证据支撑型信息检索的场景。在健身领域&#xff0c;用户常面临计划泛滥…...

Codex+Coze自动化工作流实战

Codex&#xff08;特指OpenAI的编程特化AI Agent&#xff09;与Coze&#xff08;扣子&#xff09;平台的结合&#xff0c;能够实现从自然语言描述到可运行自动化流程的端到端生成。其核心在于利用Codex强大的代码理解和生成能力&#xff0c;来编写、调试并封装符合Coze平台规范…...

用C#给PowerMill做个外挂:手把手教你写第一个连接与断开PM的WinForm工具

用C#打造PowerMill效率工具&#xff1a;从零构建自动化控制面板 在CNC编程工程师的日常工作中&#xff0c;PowerMill作为行业领先的CAM软件&#xff0c;其强大的功能背后也隐藏着大量重复性操作。每天数十次的项目打开关闭、连接状态检查、刀具路径查询等机械式点击&#xff0c…...

C166编译器内联展开机制与嵌入式性能优化

1. C166编译器运行时库函数的内联展开机制解析在嵌入式开发领域&#xff0c;C166架构因其高效的实时性能被广泛应用于工业控制领域。作为长期使用Keil C166工具链的开发者&#xff0c;我发现编译器对标准库函数的内联优化处理直接影响着代码的执行效率和内存占用。本文将深入剖…...

告别默认路径!在Win11上自定义WSL2安装位置(以Ubuntu 20.04为例)

深度掌控WSL2安装路径&#xff1a;Win11下Ubuntu 20.04的定制化部署指南 对于追求系统整洁和高效管理的开发者而言&#xff0c;Windows Subsystem for Linux 2&#xff08;WSL2&#xff09;的默认安装路径往往成为心头之患。本文将揭示如何从源头掌控WSL2的安装位置&#xff0c…...