音效模块
程序员文章站
2022-05-21 16:22:56
音效系统 1.个人思路 1.情景假设 一天,小明想听歌。于是,他拿起手机,找到音乐播放软件,选择歌曲,按下播放键,听到了想听的歌 2.过程分析 1 小明想听歌 听歌的对象,歌曲信息接收者 2 打开音乐播放软件 播放音乐的对象,音效源 3 选择歌曲 选择的数据,音效资源 3.实现思路 AudioLis ......
音效系统
音效系统
1.个人思路
-
1.情景假设
一天,小明想听歌。于是,他拿起手机,找到音乐播放软件,选择歌曲,按下播放键,听到了想听的歌
-
2.过程分析
1 小明想听歌 -> 听歌的对象,歌曲信息接收者
2 打开音乐播放软件 -> 播放音乐的对象,音效源
3 选择歌曲 -> 选择的数据,音效资源 -
3.实现思路
audiolistener: 音效的监听者
audiosources:音频控制器
audioclip:音频文件
2.代码实现
2.1 简易播放器
`using unityengine; // 添加音效源 [requirecomponent(typeof(audiosource))] public class audiomanagera : monobehaviour{ public audioclip audioclip; private audiosource _audiosource; private void start() { _audiosource = getcomponent<audiosource>(); } // 播放音效 public void playaudio(float volume = 1.0f, bool isloop = false) { _audiosource.clip = audioclip; _audiosource.volume = volume; _audiosource.loop = isloop; _audiosource.play(); debug.logformat("播放音效: {0}", audioclip.name); } }` `using unityengine; public class testa : monobehaviour { public bool isplayaudio; void start () { gameobject.addcomponent<audiomanagera>(); // 选择播放的音效 gameobject.getcomponent<audiomanagera>().audioclip = resources.load<audioclip>("audio/backgroundmusic/bgmusic"); } void update () { if (isplayaudio) { isplayaudio = false; gameobject.getcomponent<audiomanagera>().playaudio(); } } }`
2.2 如何方便的选择音效文件
` using system; using system.collections.generic; using unityengine; public interface iuploadaudio { // 加载音效资源 audioclip getaudioclip(string audioname); } [requirecomponent(typeof(audiosource))] public class audiomanagerb : monobehaviour, iuploadaudio { // 保存已经加载过的音效 private dictionary<string, audioclip> _audiodict; private audiosource _audiosource; private void start() { _audiodict = new dictionary<string, audioclip>(); _audiosource = getcomponent<audiosource>(); } // 播放音效 public void playaudio(string audioname, float volume = 1.0f, bool isloop = false) { if (!_audiodict.containskey(audioname)) { _audiodict.add(audioname, getaudioclip(audioname)); } _audiosource.clip = _audiodict[audioname]; _audiosource.volume = volume; _audiosource.loop = isloop; _audiosource.play(); } public audioclip getaudioclip(string audioname) { audioclip audioclip = resources.load<audioclip>(audioname); if (audioclip == null) { throw new exception("没有找到相应的音效资源 请确认路径:" + audioname); } return audioclip; } }`
`using unityengine; public class testb : monobehaviour { public bool isplayaudio; public string audioname; void start() { audioname = "audio/backgroundmusic/bgmusic"; gameobject.addcomponent<audiomanagerb>(); } void update() { if (isplayaudio) { isplayaudio = false; gameobject.getcomponent<audiomanagerb>().playaudio(audioname); } } }`
2.2.1 使用一个音效路径管理类
`public class audiopath { public const string background_music = "audio/backgroundmusic/bgmusic"; public const string background_music_b = "audio/backgroundmusic/bgmusicb"; public const string background_music_c = "audio/backgroundmusic/bgmusicc"; public const string background_music_d = "audio/backgroundmusic/bgmusicd"; }`
2.2.2 使用枚举组装路径
`public class audiotype { public enum dialogue { } public enum screenonclick { // 点击正确 correct, // 点击错误 error, } public enum specialeffects { } public enum backgroundmusic { // 背景音乐 bgmusic, } public enum other { } }`
`using unityengine; public class testb : monobehaviour { public bool isplayaudio; void start() { gameobject.addcomponent<audiomanagerb>(); } void update() { if (isplayaudio) { isplayaudio = false; gameobject.getcomponent<audiomanagerb>().playaudio(audiotype.backgroundmusic.bgmusic); } } }`
`using system; using system.collections.generic; using unityengine; public interface iuploadaudio { // 加载音效资源 audioclip getaudioclip(enum audioname); } [requirecomponent(typeof(audiosource))] public class audiomanagerb : monobehaviour, iuploadaudio { // 保存已经加载过的音效 private dictionary<enum, audioclip> _audiodict; private audiosource _audiosource; private const string audiopath = "audio/"; private void start() { _audiodict = new dictionary<enum, audioclip>(); _audiosource = getcomponent<audiosource>(); } // 播放音效 public void playaudio(enum audioname, float volume = 1.0f, bool isloop = false) { if (!_audiodict.containskey(audioname)) { _audiodict.add(audioname, getaudioclip(audioname)); } _audiosource.clip = _audiodict[audioname]; _audiosource.volume = volume; _audiosource.loop = isloop; _audiosource.play(); } public audioclip getaudioclip(enum audioname) { string audiotype = audioname.gettype().name; audioclip audioclip = resources.load<audioclip>(audiopath + audiotype + "/" + audioname); if (audioclip == null) { throw new exception("没有找到相应的音效资源 请确认路径:" + audioname); } return audioclip; } }`
2.3 考虑多个播放源
2.3.1 接口设置
`public interface iuploadaudioclip { // 加载音效资源 audioclip getaudioclip(enum audioname); } public interface iuploadaudiosource { // 加载音效播放源 audiosource getaudiosource(string audiosourcename); } public interface iplayaudio { // 播放音效 void playaudio(enum audioname, float volume, bool isloop, string audiosourcename); // 停止播放的音效 void stopaudio(string audiosourcename); }`
2.3.2 播放源系统
` public class uploadaudiosourcestrategy : iuploadaudiosource { // 播放的音频源 private dictionary<string, audiosource> audiosourcedict; // 音效管理器 private gameobject audiocontrol; private static int count; private readonly string currentaudioname; public uploadaudiosourcestrategy() { audiosourcedict = new dictionary<string, audiosource>(3); audiocontrol = new gameobject { name = "audiomodulecontrol" }; object.dontdestroyonload(audiocontrol); audiocontrol.addcomponent<audiolistener>(); } public audiosource getaudiosource(string audiosourcename) { if(audiosourcename.equals(string.empty)) { return getcurrentaudiosource(); } if (audiosourcedict.containskey(audiosourcename)) { return audiosourcedict[audiosourcename]; } return getcurrentaudiosource(audiosourcename); } private audiosource getcurrentaudiosource() { foreach (var source in audiosourcedict) { if (!source.value.isplaying) { return source.value; } } return getcurrentaudiosource(currentaudioname + count++); } private audiosource getcurrentaudiosource(string audiosourcename) { audiosourcedict.add(audiosourcename, audiocontrol.addcomponent<audiosource>()); return audiosourcedict[audiosourcename]; } }`
2.3.3 音效资源系统
`public class uploadaudioclipstrategy : iuploadaudioclip { // 音效路径 private readonly string audiopath; // 播放的音效 private dictionary<enum, audioclip> audioclipdict; public uploadaudioclipstrategy() { audiopath = "audio/"; audioclipdict = new dictionary<enum, audioclip>(); } public audioclip getaudioclip(enum audioname) { if (audioclipdict.containskey(audioname)) { return audioclipdict[audioname]; } audioclip clip = resources.load<audioclip>(audioclippath(audioname)); audioclipdict.add(audioname, clip); return audioclipdict[audioname]; } private string audioclippath(enum audioname) { string audiotype = audioname.gettype().name; return audiopath + audiotype + "/" + audioname; } }
`
2.3.4 音效系统
` public abstract class audiomanagerbase : iplayaudio { public iuploadaudiosource uploadaudiosource { get; protected set; } public iuploadaudioclip uploadaudioclip { get; protected set; } protected audiomanagerbase() : this(new uploadaudiosourcestrategy(), new uploadaudioclipstrategy()) { } protected audiomanagerbase(iuploadaudiosource uploadaudiosource, iuploadaudioclip uploadaudioclip) { uploadaudiosource = uploadaudiosource; uploadaudioclip = uploadaudioclip; } public void playaudio(enum audioname, float volume, bool isloop, string audiosourcename) { audioclip clip = uploadaudioclip.getaudioclip(audioname); audiosource audiosource = uploadaudiosource.getaudiosource(audiosourcename); audiosource.clip = clip; audiosource.volume = volume; audiosource.loop = isloop; audiosource.play(); } public void stopaudio(string audiosourcename) { audiosource audiosource = uploadaudiosource.getaudiosource(audiosourcename); audiosource.loop = false; audiosource.stop(); } }`
` public class audiosourcemanager : audiomanagerbase { public const string bgaudioname = "bgaudio"; #region 播放音乐的调用方式 public void playaudio(audiotype.dialogue audioname, float volume = 1.0f, bool isloop = false, string audiosourcename = "") { base.playaudio(audioname, volume, isloop, audiosourcename); } public void playaudio(audiotype.screenonclick audioname, float volume = 1.0f, bool isloop = false, string audiosourcename = "") { base.playaudio(audioname, volume, isloop, audiosourcename); } public void playaudio(audiotype.specialeffects audioname, float volume = 1.0f, bool isloop = false, string audiosourcename = "") { base.playaudio(audioname, volume, isloop, audiosourcename); } public void playaudio(audiotype.other audioname, float volume = 1.0f, bool isloop = false, string audiosourcename = "") { base.playaudio(audioname, volume, isloop, audiosourcename); } public void playaudio(audiotype.backgroundmusic audioname, string audiosourcename = bgaudioname, float volume = 1.0f, bool isloop = true) { playaudio(audioname, volume, isloop, audiosourcename); } #endregion }
`
2.3.5 播放测试
`using unityengine; public class testc : monobehaviour { private void start() { audiosourcemanager audiosourcemanager = new audiosourcemanager(); audiosourcemanager.playaudio(audiotype.backgroundmusic.bgmusic); audiosourcemanager.playaudio(audiotype.screenonclick.correct); audiosourcemanager.playaudio(audiotype.screenonclick.error); } }`
2.4 常用方法扩展
`public interface iuploadaudiosource { 。。。 // 停止选择的部分音效 void stopgroupaudio(func<string, bool> stopgroupaudio); }` `public class uploadaudiosourcestrategy : iuploadaudiosource{ 。。。 public void stopgroupaudio(func<string, bool> stopgroupaudio) { foreach (var source in audiosourcedict) { if (stopgroupaudio(source.key)) { source.value.loop = false; source.value.stop(); } } } }` `public abstract class audiomanagerbase : iplayaudio{ 。。。 public void reset(func<string, bool> stopgroupaudio) { uploadaudiosource.stopgroupaudio(stopgroupaudio); } public float playaudiotime(enum audioname) { if (uploadaudioclip.getaudioclip(audioname) == null) { debug.log("error: " + "the music file could not be found"); return 0.0f; } return uploadaudioclip.getaudioclip(audioname).length; } }` `public class audiosourcemanager : audiomanagerbase, isingleton { 。。。 private audiosourcemanager() { } public const string bgaudioname = "bgaudio"; }` `public class testc : monobehaviour { private void start() { singletonmanager.getsingleton<audiosourcemanager>().playaudio(audiotype.backgroundmusic.bgmusic); singletonmanager.getsingleton<audiosourcemanager>().playaudio(audiotype.screenonclick.correct); singletonmanager.getsingleton<audiosourcemanager>().playaudio(audiotype.screenonclick.error); } }`
上一篇: 立夏养生避开四误区 多喝啤酒能解暑
下一篇: Android关于软件关闭和显隐判断。
推荐阅读
-
模块化编程的好处(讲解编程入门基础知识)
-
Python HTML解析模块HTMLParser用法分析【爬虫工具】
-
Python时间模块datetime、time、calendar的使用方法
-
Python3使用pandas模块读写excel操作示例
-
详解python时间模块中的datetime模块
-
Python使用Paramiko模块编写脚本进行远程服务器操作
-
iNeuOS 物联网云操作系统2.0发布,集成设备容器、视图建模、机器学习三大模块
-
使用Python标准库中的wave模块绘制乐谱的简单教程
-
springboot 监控管理模块搭建的方法
-
微信小程序+微赞通用 万能门店小程序 6.9.2 后台模块+前端小程序源码