http://www.jianshu.com/p/586a5d465827?nowechat=true#

1. Unity内置了Audio功能,并且底层也是用FMOD来实现的,为什么还要不辞劳苦学习使用FMOD插件来进行音效的管理?

下面是摘录的部分内容:

The main reason to use this is that it enables your sound designers to edit, mix and master your game audio using the FMOD Studio interface while the game is running. Using FMOD studio, you can also create, e.g., a footstep sound event that will randomize the pitch and selected sound sample without the game having to know anything else than the name of the event. Using FMOD is free for non-commercial purposes and the license prices are also pretty reasonable for commercial work.
Most commercial games with decent sound design use such live mixing and centralized sound management approach, either using FMOD, WWise or some custom tools. Unity does use fmod for its own sound, but it does not provide any mixing tools and a sound designer will go insane if he/she has to manage hundreds of sound objects in the Unity editor. The main limitation of the FMOD Studio integration is that it only supports iOS, Android, Windows, Mac but no web player. If you want your sounds to work in the web player, I suggest you check out the Clockstone Audio Toolkit that provides mixing and management on top of Unity's internal sound system.

理解起来就是:

  • Unity内置的Audio内部使用的是FMOD,但是功能不够齐全,高级一点的功能如混合(Mix)等无法使用;
  • 音效管理应该和Unity工程解耦合,这样子可以减轻音效设计师的负担;
  • 使用FMOD后,游戏中我们只需要关心sound event名字就可以了,对具体音效资源不会产生依赖;
  • 目前FMOD支持Windows, Mac OSX, Android, iOS,其实官方文档中说了对XBOX One,PlayStation系统等系统都有支持;

结合FMOD Studio的官方文档,我们可以总结出使用FMOD的如下优点

  • 使用FMOD我们可以使用更少的资源创建更加高级和丰富的音效,减少运行时内存资源消耗;
  • 音效管理只需要在FMOD Studio中管理好即可,不需关心具体Unity工程,方便音效管理;
  • 编程人员只需要依赖于各种字符串形式的Sound Event和简单的播放API即可,使用简单;
  • 平台支持较为完善。

2. FMOD的基本使用过程

FMOD的使用过程比较简单,复杂之处在于FMOD Studio的使用,音效资源编辑完成后的使用较为简单。具体流程参见下图:

具体过程如下:
1. 使用FMOD Studio编辑器编辑原始音效资源,创建各种音效;
2. 导入Unity Game Project;
3. 通过FMOD Plugin的API进行播放。

3. 简单例子

FMOD Studio部分:
1. 下载FMOD Studio;
2. 打开FMOD Studio即创建一个新工程,Ctrl + S 确定工程保存位置;
3. Window->Audio Bin打开Audio Bin窗口,用于选择工程需要的声音文件,File->Import Audio Files选择工程需要的声音文件;
4. FMOD Studio中左侧面板Event Tab栏中,右击选择New Event,表示创建一个新的音效(下图创建了一个test音效);

5. 将Audio bin面板中的将音效文件拖到FMOD Studio的Audio 1中,如下图所示,拖入了两个声音资源进去组成了一个音效:

6. 右击test Event,选择Assign to Bank->Master bank;
7. Ctrl + s,然后File->Build,然后File->Export GUIDs。
8. over

Unity部分:
1. 下载fmodstudio10402.unitypackage,并导入Unity,此时菜单栏会多出一个FMOD选项;
2. FMOD->Import Banks,打开刚刚FMOD Studio创建的工程的Build目录,Import之,Import的资源会在Assets/StreamingAssets目录下;
3. 选择Main Camera,然后选择Component->Scripts->FMOD Listener;
4. 创建一个Empty GameObject,然后Create And Add一个Script,附加如下代码内容,即可实现播放音效:

using UnityEngine;
using System.Collections;
using FMOD.Studio;public class TestFMOD : MonoBehaviour {FMOD.Studio.EventInstance testInstance;string snd = "event:/test";// Use this for initializationvoid Start () {testInstance = FMOD_StudioSystem.instance.GetEvent(snd);if (testInstance != null){testInstance.start();}}
}

2. 参数详解

FMOD Studio工程

FMOD Studio工程中,所有的声音文件都是以Event的形式存在的,这些Event都是通过字符串的形式来进行表示的;
目前对FMOD Studio工具的使用只是创建一个简单的Event,在FMOD Studio的安装目录中有文档可以参考。

  • 是否是STREAM类型:
  • 音效是否loop:

EventInstance参数

  • position:决定音量,距离越远,音量越小;
  • velocity:决定音高,速度越快,音量越大。

注意点:
需要封装的其实只有两个东西,一个是更新EventInstance.updateAttribute方法,FMOD的实现在其中不停的获取Transfrom Component,这是效率很低的地方,可以提供一个只需要Tranform参数的方法来供调用;另一个提供一个Play方法供外部进行调用,参数是Event即可。

以前出现的问题:

  1. 连续播放多个声音的时候,后面的声音将前面的声音打断了。初步估计是以为当时的系统中使用了对象池,每次都是从对象池中进行取得EventInstance,而不是创建新的。实际上如果对同一个EventInstance进行重复调用start函数时,会从头开始重新播放。
    例子中的声音文件播放的时长为2.6s,没有出现后面的声音阻断前面的声音的情况。

    IEnumerator Play2Sound()
    {for(int i=0; i<2; ++i){EventInstance instance = FMOD_StudioSystem.instance.GetEvent(snd);instance.start();yield return new WaitForSeconds(1f);}
    }

    而这个例子中,重复的start则会将上次的声音打断

    IEnumerator Play2Sound()
    {for(int i=0; i<2; ++i){if (null == testInstance){testInstance = FMOD_StudioSystem.instance.GetEvent(snd);}testInstance.start();yield return new WaitForSeconds(1f);}
    }
  2. 一个音乐多次重复播放的时候容易出现刺刺的声音
    泡爷的方案是在五帧之内则不允许再次播放,但是我没有遇到这种现象,测试代码如下:

     IEnumerator TestLargetScaleSnd(){while (true){for(int i=0; i<26; ++i){EventInstance instance = FMOD_StudioSystem.instance.GetEvent(snd);instance.start();yield return new WaitForSeconds(0.1f);}}}
  3. 在使用FMOD的时候,york同学遇到一个情况,就是如果设置一个回调函数,则在MonoDevelop设置断点时总是crash掉。而我实验的结果是在大量播放一个声音时,如果设置回调函数,则Unity会挂掉。因此暂且总结为不要使用EventInstance的callback方法设置回调函数。
    实验代码如下(五个声音以上同时播放则会挂掉,少则不会):

     IEnumerator TestLargetScaleSnd(){//while (true){for(int i=0; i<5; ++i){EventInstance instance = FMOD_StudioSystem.instance.GetEvent(snd);instance.setCallback(callbackFunc);instance.start();yield return new WaitForSeconds(0.1f);}}}
     RESULT callbackFunc(EVENT_CALLBACK_TYPE type, IntPtr eventInstance, IntPtr parameters)
     {return RESULT.OK;}

3. 实践总结

FMOD的已知实验总结出以下三点:
1. Unity Project只需要使用FMOD.Studio.EvenInstance就可以了,Unity Project中不需要对EventInstance的内存池管理,只需要对它的position属性进行管理;
2. 我们还需要一个封装的接口来提供声音的播放,这个接口为
void Play(string snd);
3. _3D_ATTRIBUTES用于设置EventInstance的属性,我们设置的属性目前只有position属性,而这个属性由于需要随着角色的移动而更新,因此需要频繁调用。而_3D_ATTRIBUTES的to3DAttributes方法每次都要去取GameObject的Transform,消耗较大,因此我们需要封装一个to3DAttributes(Transform)方法,根据缓存的Transform来进行。

to3DAttributes方法的封装如下:

public class FModUtils
{static public _3D_ATTRIBUTES to3DAttributes(Transform go){FMOD.Studio._3D_ATTRIBUTES attributes = new FMOD.Studio._3D_ATTRIBUTES();attributes.forward = UnityUtil.toFMODVector(go.forward);attributes.up = UnityUtil.toFMODVector(go.up);attributes.position = UnityUtil.toFMODVector(go.position);if (go.rigidbody)attributes.velocity = UnityUtil.toFMODVector(go.gameObject.rigidbody.velocity);return attributes;}
}

总结1和2则通过封装一个FModCom即可,需要播放声音的GameObject需要挂接这个脚本,并在需要播放声音的时候调用其中的Play接口,代码如下:

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using FMOD.Studio;
using com.morefun.kl;public class FMODCom : MonoBehaviour {[HideInInspector]public float updateTime = 0.5f;private List<EventInstance> m_soundList;private Transform m_trans;void Awake(){m_trans = this.transform;m_soundList = new List<EventInstance>();}// Use this for initializationvoid Start () {StartCoroutine(updateSnd());}// 播放声音接口public void Play(string snd){EventInstance sndEvent = FMOD_StudioSystem.instance.GetEvent(snd);if (null == sndEvent) return;sndEvent.set3DAttributes(FModUtils.to3DAttributes(m_trans));sndEvent.start();addToUpdateAttribute(sndEvent);}IEnumerator updateSnd(){while (true){PLAYBACK_STATE state;//将stopped的音效从soundList中删除//在循环中要删除对象,因此不能用foreachfor (int i = 0; i < m_soundList.Count; ++i){EventInstance eventIns = m_soundList[i];eventIns.getPlaybackState(out state);if (PLAYBACK_STATE.PLAYING == state){eventIns.set3DAttributes(FModUtils.to3DAttributes(m_trans));}else if (PLAYBACK_STATE.STOPPED == state){m_soundList.RemoveAt(i);i--;}}yield return new WaitForSeconds(updateTime);}}void addToUpdateAttribute(EventInstance value){if (!m_soundList.Contains(value)){m_soundList.Add(value);}}
}

工程使用FMOD的过程如下:
1. 在Main Camere上Attach一个FMOD Listener脚本(Component->Scripts->FMOD_Listener);
2. 需要播放音效的GameObject上Attach FModCom脚本,需要播放音效的时候调用FModCom.Play接口。

4. 音频编码和解码

普通音频文件根据编码格式不同分为两类:

  • 无损格式,例如WAV,PCM,TTA,FLAC,AU,APE,TAK,WavPack(WV)
  • 有损格式,例如MP3,Windows Media Audio(WMA),Ogg Vorbis(OGG),AAC

我们一般使用的是WAV,MP3和OGG格式的音频文件,一般WAV是MP3和OGG文件的十倍左右大小。

音频文件的解析过程分为两部:
1. 加载入内存;
2. 解码成波形文件。
二者都是比较消耗时间的地方,解码的优化在于是否有硬件优化,IO的优化在于能否部分加载连续IO。

FMOD自身提供了音频编码格式.BANK,可以在编辑器中编辑Quality选项选择最终生成的音乐品质,我在实验中选择的Quality是80%,结果如下:
原始音效WAV文件大小为117KB,生成的BANK文件大小为50KB;
原始音效MP3文件大小是2.78MB, 生成的BANK文件大小是4.82MB。
FMOD统一了格式,使得我们不需要再关心具体的音频文件格式和转化。带来的一个缺点是音频文件在安装包中占据的体积会增大,这个需要我们调整Quality参数来进行设置。

上次飞车的分享中提到Android不支持音频的硬件解码,因此如果需要通过CPU解码游戏背景音这种类型音效则非常耗时,他们的经验是:

  • 特效音一次性整体载入;
  • 背景音则通过string的形式进行部分载入。

FMOD中支持上述两种方式的加载。在FMOD中,如果原始的音效资源是压缩类型的(mp3, ogg等),则可以选择是否以STREAM的方式进行加载;如果是非压缩类型的(wav等),则只能以非STREAM的方式加载进内存。
因此我们的解决方案是:

  • 特效音在FMOD中设置成非STREAM方式;
  • 背景音设置成STREAM方式。

Ref:

http://perttuh.blogspot.com/2013/10/unity-and-fmod-integration.html
http://m-klier.de/2014/06/09/unity3d-angry-bots-fmod-part-1/
FMOD Studio User Manual.pdf

unity音效插件—— FMOD学习相关推荐

  1. UNITY中FMOD音效插件使用

    在UNITY中使用FMOD插件,直接控制音乐,音效. FMOD下载 FMOD STUDIO的版本与插件要保持一致. FMOD STUDIO使用教程 UNITY引入package FMOD - Edit ...

  2. unity中使用fmod音频插件1

    1.安装音频编辑软件 插件下载网址:https://www.fmod.com/download fmod api网址:https://www.fmod.com/resources/documentat ...

  3. Unity Cinemachine插件学习笔记,实现单目标和多目标之间切换

    Unity Cinemachine插件学习笔记,实现单目标和多目标之间切换 *版本要求Unity2017.1及以上. 参考资料: [官方] Unity 2017.1正式版发布 Cinemachine插 ...

  4. Unity Cinemachine插件学习笔记

    以下都是转载内容,能够比较直观的学习一些基础内容.现在的Cinemachine更新了许多新的功能,但是Cinemachine插件都ExamplesScences,去看一下官方例子和文档来学习更佳 *版 ...

  5. Unity Cinemachine插件学习笔记,结合Timeline实现简单场景动画

    Unity Cinemachine插件学习笔记,结合Timeline实现简单场景动画 *版本要求Unity2017.1及以上. 参考资料: [官方] Unity 2017.1正式版发布 [Unity] ...

  6. Unity常见插件汇总

    Unity常见插件汇总 介绍 收集了相关的Unity插件,供大家学习使用,如果用于商业活动,请购买相关版权 插件列表 1. A* Pathfinding Project 一个功能强大并且易于使用的 U ...

  7. NDK学习笔记:一起来变萝莉音!FMOD学习总结(下)

    NDK学习笔记:一起来变萝莉音!FMOD学习总结(下) 一.创建自己的变音demo 上一节我已经能够在AndroidStudio上跑起了fmod的基础教程.还有疑问的同学可以重新阅读跟着来跑一次.这章 ...

  8. Unity优化手机游戏学习教程

    流派:电子学习| MP4 |视频:h264,1280×720 |音频:AAC,48.0 KHz 语言:英语+中英文字幕(根据原英文字幕机译更准确)|大小解压后:3.69 GB |时长:6h 44m 创 ...

  9. MMD的unity导入插件

    2019独角兽企业重金招聘Python工程师标准>>> 存在一个mmd模型的unity导入插件: 导入了mmd的物理,将模型每个部位通过 custom的joint进行连接,设定物理属 ...

  10. 安卓插件化学习 - 类的加载

    安卓插件化学习 - 类的加载 引言 一.类的加载 1. 原理 2. 代码 2.1 宿主apk代码 2.1.1 插件管理器 2.1.2 配置文件 2.1.3 插件初始化 2.1.4 调用插件方法 2.2 ...

最新文章

  1. crysis3 android,Crytek谈安卓版《Crysis 3》:Tegra X1图形性能OK,瓶颈是CPU
  2. 接口测试指导方案 转:紫漪
  3. cocos2dx集成友盟社会化分享图片崩溃问题
  4. 前端路由的两种实现原理
  5. SQL Serverf 索引 - 索引压缩 、附加特性 第十篇
  6. 批处理(bat)实现SQLServer数据库备份与还原
  7. stft isar成像 matlab,基于时频分析的ISAR成像
  8. 【译】理解JavaScript闭包——新手指南
  9. centos elasticsearch7 安装_SkyWalking学习笔记(CentOS环境)
  10. LeetCode 一题多解
  11. 12通过作用域链实现闭包
  12. freeimage.dll
  13. 十七.降维之谱分解和奇异值分解
  14. SVN版本管理的回滚(SmartSVN)
  15. 如何让新建网站被搜索引擎快速收录
  16. 嗯,我是一个偏执狂。
  17. 更换一寸照片底色蓝色底,红色底白底一寸照怎么做ps教程简单快速快捷方法办法ps学习ps教学ps教程
  18. 2021华数杯数学建模选题建议
  19. 隐藏桌面和控制面板网络连接
  20. Django设置成中文

热门文章

  1. 系统集成项目管理工程师2022年上半年广东卷下午案例分析题及答案
  2. c语言编译器pellc,单片机C语言程序的设计实训100例_基于8051+PROTEUS仿真1
  3. linux下shell脚本编程2
  4. 最新Unity 3D游戏开发学习资料集合
  5. PMP培训机构转个圈
  6. 局域网文件共享手机访问电脑文件软件
  7. Java排序算法——选择排序(Selection Sort)
  8. 软件测试理论基础(一)
  9. python 安装包国内源
  10. 【学习】在Windows10平台使用Docker ToolBox安装docker(一)