Unity声音管理系统笔记

需求

  1. 在各个场景可以打开设置面板,设置音乐、UI音效和所有其他音效的音量;

分析

管理器在各个场景都存在,可以:

  1. 不继承MonoBehavior,就不能和AudioSource挂在一个对象,也不能通过拖指定音乐和UI音效AudioSource。如果在场景里建好AudioSource,让它用GameObject.Find()或transform.Find()找AudioSource,那么每个场景都要创建,容易漏掉。所以这条路最好让管理器新建对象,添加AudioSource。
  2. 继承MonoBehavior,可以拖了,每个场景都建一个,同理容易漏建,不是好方案。
  3. 继承MonoBehavior,并且DontDestroyOnLoad。

总之,手动在每个场景创建管理器不是好方案,如果又想拖,那么继承MonoBehavior,DontDestroyOnLoad可能是最好的方案。

可以是管理器有场景里所有AudioSource的引用,并且知道哪个AudioSource是音乐,哪些是音效。初始化和改变音量时把相应的AudioSource的音量写成用户设置的,这里称为"中心改变地方"。

也可以是所有的播放声音函数使用声音管理器封装的函数,里面播放前先把音量设置为用户设置的。这里称为"地方读取中心"。

中心改变地方

管理器怎么分清哪个是音乐,哪些是音效?可以把音乐AudioSource和UI音效AudioSource单独拖。其他通过FindObjectsByType(),再和音乐、UI音效AudioSource对比判断是其他AudioSource。

但是转换场景时要重新获得一遍场景所有的AudioSource。管理器怎么知道什么时候切换场景了?还是需要各场景的管理器调用。

如果还有运行中创建AudioSource,声音管理器又怎么知道?创建AudioSource的脚本通知一下声音管理器?

这样想下去,越来越发现"中心改变地方",设计不可行,或者说越来越变成"地方读取中心"。管理器缺少太多信息,包括AudioSource种类,生命周期。

地方读取中心

需要把项目所有的audioSource.Play()替换成自己封装的方法。先找到一个audioSource.Play(),再对Play()寻找引用,替换audioSource.Play()。

cs 复制代码
public void MyPlaySound(AudioSource audioSource){
        audioSource.volume=DataManager.Instance.settingsData.soundVolume;
        audioSource.Play();
    }

音乐在游戏开始运行时开始播放,需要在初始化、玩家改变音量时设置音量。各AudioSource知道自己是音乐、UI音效还是其他音效,也知道自己什么时候播放,无需关心场景有没有切换。

然后......好像没什么问题了。

总结

总结下来,这种管理系统的设计有点反直觉,看起来是"管理器",其实是各地方组件要求管理器管理自己。

相关推荐
Xudde.1 小时前
CVE-2017-9993漏洞复现
笔记·学习·安全·web安全
FakeOccupational1 小时前
【电路笔记 STM32】Cortex-M7 UART 中断模式(串口接收中断+串口空闲中断)
笔记·stm32·单片机
小李不想当小白1 小时前
USART串口协议(STM32标准库学习笔记)
经验分享·笔记·stm32·单片机·嵌入式硬件·学习
AOI小白新手上路2 小时前
视频去雨·论文蒸馏笔记:从物理先验到状态空间模型
数据库·笔记·音视频
AOI小白新手上路3 小时前
DRSformer·论文蒸馏笔记:可学习 Top-k 稀疏注意力去雨网络
网络·笔记·学习
AOI小白新手上路4 小时前
单幅图像去雨·论文蒸馏笔记:统一评测、方法谱系与 HQ-RAIN 新基准
笔记
糖炒栗子要加糖5 小时前
Windows 大量小文件复制太慢?使用 Robocopy 多线程加速
笔记·提升效率
2601_961146205 小时前
我的等离子表面处理设备周度保养折腾记录
笔记·设备·设备选型
小新科研测评5 小时前
文献管理工具同步太麻烦?2026年4款多端同步工具实测,换设备不丢笔记
论文阅读·人工智能·笔记·ai·电脑
龙仔7257 小时前
RustDesk 1.5.0 升级安装故障处理笔记
笔记