在UNITY中使用FMOD插件,直接控制音乐,音效。
FMOD下载
FMOD STUDIO的版本与插件要保持一致。
FMOD STUDIO使用教程
UNITY引入package
FMOD - Edit Setting 3个选项:Project,Single Platform Build,Multiple Platform Build
Project路径指定FMOD工程,其余2个路径指定FMOD导出的bank所在文件夹。
可以指定UNITY工程外路径,如果需要多人同步也可以用Assets\路径 (Mac下用 [/])
指定后插件会自动在Assets/StreamingAssets将bank导入。
注意:导出安卓工程时,FMOD的BANK文件没有被加密放在assets\bin文件夹内,而是直接在assets文件夹下
Live Update选项Enabled时,可以直接在FMOD STUDIO中调试音乐音效。
UNITY内代码部分:
using UnityEngine;
using System;
using ;
using ;
using FMODUnity;
public class SoundManager <T>: MonoBehaviour where T: Component{
protected static T _instance;
public static T instance {
get {
if (_instance.IsNull())
_instance = FindObjectOfType<T>();
return _instance;
}
}
public static bool DoesInstanceExist {
get {
return instance != null;
}
}
public BGMPathDefinition[] BGMPathDefinitions;
protected Dictionary<BGMType, string> BGMPathDict;
protected BGMType currentAmbientAudio;
//一个声音实例,可控制。
//循环播放的可以创建一个,要手动release, OneShot 为true播放完自动release.
///docs/content/generated/studio_api_EventInstance.html
///docs/content/generated/FMOD_Studio_EventDescription_IsOneshot.html
protected EventInstance BGMEvent;
用来读取声音在工程里面的设置信息,用不到
/docs/content/generated/studio_api_EventDescription.html
//private EventDescription musicDescription;
protected Dictionary<string, EventInstance> loopingSoundEvents = new Dictionary<string, EventInstance>();
protected List<EventInstance> pausedSoundEvents;
protected const int minPathLength = 7;
protected virtual void Awake() {
_instance = GetComponent<T>();
BGMPathDict = new Dictionary<BGMType, string>();
foreach (var ambientAudioDefinition in BGMPathDefinitions) {
(, );
}
}
protected virtual void OnDestroy() {
StopAndReleaseAll();
if (BGMEvent != null) {
(STOP_MODE.IMMEDIATE);
();
}
_instance = null;
}
public virtual void StopAndReleaseAll() {
foreach (var sound in ) {
if (sound == null)
continue;
(STOP_MODE.IMMEDIATE);
();
}
();
}
public virtual void pauseAll() {
pausedSoundEvents = new List<EventInstance>();
foreach (var loopingInstance in ) {
if (loopingInstance == null)
continue;
PLAYBACK_STATE state;
(out state);
if (state == PLAYBACK_STATE.PLAYING
|| state == PLAYBACK_STATE.STARTING) {
(true);
(loopingInstance);
}
}
PauseBGM(true);
}
public virtual void resumeAll() {
PauseBGM(!);
if (! || pausedSoundEvents == null)
return;
foreach (var pausedSound in pausedSoundEvents) {
(false);
}
}
#region BGM
public virtual void PlayBGM(BGMType type) {
currentAmbientAudio = type;
if () {
CheckBGMEventInstance();
}
}
public virtual void PauseBGM(bool pause) {
if (BGMEvent == null)
CheckBGMEventInstance();
if (BGMEvent != null)
(pause);
}
protected void CheckBGMEventInstance() {
if ((currentAmbientAudio)) {
//停止之前的,最好可以通过参数变化背景音乐
if (BGMEvent != null) {
(STOP_MODE.IMMEDIATE);
();
}
BGMEvent = (BGMPathDict[currentAmbientAudio]);
();
}
}
#endregion
#region SFX
/// <summary>
/// 播放一次,不能改变任何参数
/// </summary>
public virtual void PlaySoundOnce(string sound) {
if (! || (sound))
return;
if ( < minPathLength) {
("Wrong Sound Path:" + sound);
return;
}
(sound);
}
/ <summary>
/ 目标位置播放一次(位置不变)
/ </summary>
//public void PlaySoundOnce(string Event, Vector3 position) {
// if ()
// (Event, position);
//}
/ <summary>
/ 播放一次,位置在attach上(跟着attach移动)
/ </summary>
//public void PlaySoundOnce(string Event, GameObject attach) {
// if ()
// (Event, attach);
//}
/// <summary>
/// 循环播放,要Fmod工程内OneShot为false
/// </summary>
public virtual EventInstance PlayLoopSounds(string sound) {
if (! || (sound))
return null;
if ( < minPathLength) {
("Wrong Sound Path:" + sound);
return null;
}
if (HavaEventInstance(sound)) {
loopingSoundEvents[sound].start();
return loopingSoundEvents[sound];
}
var newInstance = (sound);
();
loopingSoundEvents[sound] = newInstance;
return newInstance;
}
/// <summary>
/// 暂停指定循环音效
/// </summary>
public bool PauseSound(string sound, bool pause = true) {
if (HavaEventInstance(sound)) {
var result = loopingSoundEvents[sound].setPaused(pause && );
return result == ;
}
return false;
}
/// <summary>
/// 停止指定循环音效,并释放
/// </summary>
public bool StopSound(string sound) {
if (HavaEventInstance(sound)) {
var result = loopingSoundEvents[sound].stop(STOP_MODE.IMMEDIATE);
loopingSoundEvents[sound].release();
(sound);
return result == ;
}
return false;
}
protected bool HavaEventInstance(string sound) {
return !(sound) && (sound) && !loopingSoundEvents[sound].IsNull();
}
#endregion
//void OnApplicationPause(bool didPause) {
// if (didPause) {
// pauseAll();
// }
// else {
// resumeAll();
// }
//}
void OnApplicationFocus(bool focus) {
if (focus) {
resumeAll();
}
else {
pauseAll();
}
}
}
[Serializable]
public class BGMPathDefinition {
public BGMType ambientAudioType;
[EventRef]
public string path;
}
public enum BGMType {
Mainmenu = 0,
IngameRunning = 20,
}
FMOD STUDIO的版本与插件要保持一致。
FMOD STUDIO的版本与插件要保持一致。