268 lines
8.1 KiB
C#
268 lines
8.1 KiB
C#
using System.Collections.Generic;
|
|
using AibisDream.FixSystem;
|
|
using AibisDream.Framework;
|
|
using FMOD;
|
|
using FMOD.Studio;
|
|
using FMODUnity;
|
|
using STOP_MODE = FMOD.Studio.STOP_MODE;
|
|
|
|
namespace AibisDream.Kit
|
|
{
|
|
public class AudioManager : Singleton<AudioManager>, IAudioManager
|
|
{
|
|
private const string AmbStateName = "scene";
|
|
|
|
public EventReference ambEvent;
|
|
|
|
#region Event实例
|
|
|
|
private EventInstance _ambInstance;
|
|
private EventInstance _voiceInstance;
|
|
private readonly Dictionary<string, EventInstance> _musicDict = new();
|
|
private readonly Dictionary<string, EventInstance> _sfxDict = new();
|
|
|
|
#endregion
|
|
|
|
#region 事件索引
|
|
|
|
private List<IUnRegister> _removeTrigger;
|
|
|
|
#endregion
|
|
|
|
private void Start()
|
|
{
|
|
// 注册事件
|
|
RegisterEvent();
|
|
// 启动AMB
|
|
InitAmb();
|
|
}
|
|
|
|
private void RegisterEvent()
|
|
{
|
|
// 语音相关
|
|
EnumEventSystem.Global.Register<DialogEventEnum, DialogText>(DialogEventEnum.LineStart, OnLineStart);
|
|
EnumEventSystem.Global.Register(DialogEventEnum.LineShown, OnLineShown);
|
|
// 场景切换相关
|
|
EnumEventSystem.Global.Register<EventEnum, string>(EventEnum.SceneLoad, OnSceneLoad);
|
|
EnumEventSystem.Global.Register<EventEnum, FixState>(EventEnum.FixStateSwitch, OnFixStateChange);
|
|
EnumEventSystem.Global.Register(EventEnum.SceneUnload, OnSceneUnload);
|
|
}
|
|
|
|
#region AMB相关
|
|
|
|
private void InitAmb()
|
|
{
|
|
_ambInstance = RuntimeManager.CreateInstance(ambEvent);
|
|
_ambInstance.start();
|
|
}
|
|
|
|
public void ChangeAmb(AmbState state)
|
|
{
|
|
RuntimeManager.StudioSystem.setParameterByName(AmbStateName, (float)state);
|
|
}
|
|
|
|
public void SetGlobalParam(string paramName, float value)
|
|
{
|
|
RuntimeManager.StudioSystem.setParameterByName(paramName, value);
|
|
}
|
|
|
|
private void OnSceneLoad(string loadingScene)
|
|
{
|
|
// 场景加载时切换AMB
|
|
var state = MatchAmbState(loadingScene);
|
|
ChangeAmb(state);
|
|
}
|
|
|
|
private void OnSceneUnload()
|
|
{
|
|
ChangeAmb(AmbState.Main);
|
|
}
|
|
|
|
private void OnFixStateChange(FixState nextState)
|
|
{
|
|
// 状态切换时加载
|
|
var state = MatchAmbState(nextState);
|
|
ChangeAmb(state);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region 音乐相关
|
|
|
|
public void PlayMusic(string eventName, string audioKey = null)
|
|
{
|
|
var eventPath = FormatEventPath(eventName);
|
|
|
|
var key = string.IsNullOrEmpty(audioKey) ? eventName : audioKey;
|
|
if (_musicDict.TryGetValue(key, out var oldMusic))
|
|
{
|
|
oldMusic.stop(STOP_MODE.IMMEDIATE);
|
|
oldMusic.release();
|
|
_musicDict.Remove(key);
|
|
}
|
|
|
|
var newMusic = RuntimeManager.CreateInstance(eventPath);
|
|
_musicDict[key] = newMusic;
|
|
newMusic.start();
|
|
}
|
|
|
|
public void StopMusic(string key, STOP_MODE stopMode)
|
|
{
|
|
if (_musicDict.TryGetValue(key, out var oldMusic))
|
|
{
|
|
oldMusic.stop(stopMode);
|
|
oldMusic.release();
|
|
_musicDict.Remove(key);
|
|
}
|
|
}
|
|
|
|
public void SetMusicParam(string key, string param, float paramValue)
|
|
{
|
|
if (_musicDict.TryGetValue(key, out var music))
|
|
{
|
|
music.setParameterByName(param, paramValue);
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
public void OnLineStart(DialogText dialogText)
|
|
{
|
|
if (_voiceInstance.IsPlaying())
|
|
{
|
|
_voiceInstance.stop(STOP_MODE.IMMEDIATE);
|
|
_voiceInstance.release();
|
|
}
|
|
|
|
if (string.IsNullOrEmpty(dialogText.actor.voicePath) || !FModEx.IsEventExist(dialogText.actor.VoicePath))
|
|
{
|
|
return;
|
|
}
|
|
|
|
_voiceInstance = RuntimeManager.CreateInstance(dialogText.actor.VoicePath);
|
|
_voiceInstance.start();
|
|
}
|
|
|
|
public void OnLineShown()
|
|
{
|
|
if (_voiceInstance.isValid())
|
|
{
|
|
_voiceInstance.stop(STOP_MODE.IMMEDIATE);
|
|
_voiceInstance.release();
|
|
}
|
|
}
|
|
|
|
public void PlaySfx(string eventName, string audioKey = null)
|
|
{
|
|
var eventPath = FormatEventPath(eventName);
|
|
var key = string.IsNullOrEmpty(audioKey) ? eventName : audioKey;
|
|
if (_sfxDict.TryGetValue(key, out var oldSfx))
|
|
{
|
|
oldSfx.stop(STOP_MODE.IMMEDIATE);
|
|
oldSfx.release();
|
|
_sfxDict.Remove(key);
|
|
}
|
|
|
|
var newSfx = RuntimeManager.CreateInstance(eventPath);
|
|
if (newSfx.GetDescription().isOneshot(out var isOneshot) != RESULT.OK || !isOneshot)
|
|
{
|
|
_sfxDict[key] = newSfx;
|
|
}
|
|
|
|
newSfx.start();
|
|
}
|
|
|
|
public void StopSfx(string key, STOP_MODE stopMode)
|
|
{
|
|
if (_sfxDict.TryGetValue(key, out var oldSfx))
|
|
{
|
|
oldSfx.stop(stopMode);
|
|
oldSfx.release();
|
|
_musicDict.Remove(key);
|
|
}
|
|
}
|
|
|
|
public void SetSfxParam(string key, string paramName, float paramValue)
|
|
{
|
|
if (_sfxDict.TryGetValue(key, out var sfx))
|
|
{
|
|
sfx.setParameterByName(paramName, paramValue);
|
|
}
|
|
}
|
|
|
|
#region 一些静态方法
|
|
|
|
private static string FormatEventPath(string eventName)
|
|
{
|
|
return eventName.StartsWith("event:/") ? eventName : $"event:/{eventName}";
|
|
}
|
|
|
|
private static AmbState MatchAmbState(string key)
|
|
{
|
|
return key switch
|
|
{
|
|
"ExpressFixScene" => AmbState.Clinic,
|
|
"ShitouHeadiFixScene" => AmbState.Clinic,
|
|
"PeipeiFixScene" => AmbState.Clinic,
|
|
"Bridge" => AmbState.Footbridge,
|
|
"SkyBridge" => AmbState.Footbridge,
|
|
"SubWay" => AmbState.Subway,
|
|
"ClinicOut" => AmbState.Outside,
|
|
"OutSideSceneTemp" => AmbState.Outside,
|
|
_ => AmbState.Main
|
|
};
|
|
}
|
|
|
|
private static AmbState MatchAmbState(FixState fixState)
|
|
{
|
|
return fixState switch
|
|
{
|
|
FixState.Clinic => AmbState.Clinic,
|
|
FixState.Engine => AmbState.Engine,
|
|
FixState.BodyModule => AmbState.Body,
|
|
FixState.Gear => AmbState.GearBox,
|
|
FixState.UF => AmbState.UF,
|
|
FixState.Eye => AmbState.Eye,
|
|
FixState.Memory => AmbState.Memory,
|
|
_ => AmbState.Main
|
|
};
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
|
|
public interface IAudioManager
|
|
{
|
|
// Yarn音频接口
|
|
public void PlayMusic(string eventName, string audioKey);
|
|
public void StopMusic(string eventName, STOP_MODE stopMode);
|
|
public void SetMusicParam(string eventName, string paramName, float paramValue);
|
|
|
|
// AMB参数变化
|
|
public void ChangeAmb(AmbState state);
|
|
public void SetGlobalParam(string paramName, float value);
|
|
|
|
// 语音相关
|
|
public void OnLineStart(DialogText dialogText);
|
|
public void OnLineShown();
|
|
|
|
// 交互相关
|
|
public void PlaySfx(string eventName, string audioKey);
|
|
public void StopSfx(string eventName, STOP_MODE stopMode);
|
|
public void SetSfxParam(string eventName, string paramName, float paramValue);
|
|
}
|
|
|
|
public class AudioData : IData
|
|
{
|
|
public string ambState;
|
|
public List<string> sfxNames = new();
|
|
public List<string> musicNames = new();
|
|
|
|
public void Load()
|
|
{
|
|
throw new System.NotImplementedException();
|
|
}
|
|
}
|
|
}
|
|
|