538 lines
17 KiB
Lua
538 lines
17 KiB
Lua
--region *.lua
|
||
--Date
|
||
--此文件由[BabeLua]插件自动生成
|
||
local _IsLog = false
|
||
local function __DebugLog(content)
|
||
if _IsLog then
|
||
Log("<color=#aaaa55>"..content.."</color>")
|
||
end
|
||
end
|
||
|
||
SoundManager = { }
|
||
|
||
local eAudioType = {
|
||
uiAudio = 1,
|
||
bgAudio = 2,
|
||
amAudio = 3,
|
||
}
|
||
|
||
AUDIO_RUN_TYPE = { -- 音效切换执行方式
|
||
SEQ = 1, -- 顺序
|
||
CONC = 2 -- 并发
|
||
}
|
||
AUDIO_FADE_TYPE = { -- 音效淡入淡出方式
|
||
FADE_OUT_AND_IN = 1, -- 淡入淡出
|
||
FADE_OUT_NOT_IN = 2, -- 淡出不淡入
|
||
FADE_IN_NOT_OUT = 3, -- 淡入不淡出
|
||
DIRECT_CHANGE = 4 -- 直接变化
|
||
}
|
||
|
||
SoundManager.soundChannelCount = 20
|
||
SoundManager.soundVolume = 1
|
||
SoundManager.backgroundSoundVolume = 1
|
||
|
||
SoundManager.cachePlayTime = 0.16
|
||
|
||
|
||
-- 相同音效的播放间隔
|
||
local _AudioPlayCD = 0.1
|
||
local _AudioPlayList = {}
|
||
|
||
local _sfx_enabled = true
|
||
local _bgm_enabled = true
|
||
local _amb_enabled = true
|
||
|
||
local _backgroundSound = {}
|
||
local _backgroundRes
|
||
|
||
local _AmbientChannel = {}
|
||
local _AmbientRes
|
||
|
||
local _soundChannel = { }
|
||
local AudioSource = UnityEngine.AudioSource
|
||
local AudioConfig = {}
|
||
local SoundDef = {
|
||
"Music", --背景音
|
||
"Ambient", --环境音效
|
||
"common", --普通UI音效
|
||
"skill", --技能音效 --[[
|
||
"buff", --技能音效 4,5,6,7统一使用skill音轨进行处理
|
||
"monster", --技能音效
|
||
"yiyao", --技能音效 ]]
|
||
|
||
"footsteps", -- 脚步声
|
||
"other", -- 其他ui音效
|
||
"special", -- 特殊ui音效
|
||
"Voice", -- 配音音效
|
||
}
|
||
local _node
|
||
function SoundManager.Clear()
|
||
if _node ~= nil then
|
||
SoundManager.ClearResource()
|
||
GameObject.Destroy(_node)
|
||
_node = nil
|
||
end
|
||
end
|
||
|
||
function SoundManager.ClearResource()
|
||
-- 资源回收
|
||
for i = 1, SoundManager.soundChannelCount do
|
||
local audioUnit = _soundChannel[i]
|
||
if audioUnit then
|
||
audioUnit.audio:Stop()
|
||
if audioUnit.audio.clip then
|
||
if audioUnit.audioType == eAudioType.uiAudio then
|
||
poolManager:UnLoadAsset(audioUnit.audio.clip.name,audioUnit.audio.clip, PoolManager.AssetType.MediaUI)
|
||
audioUnit.audio.clip = nil
|
||
end
|
||
end
|
||
end
|
||
end
|
||
|
||
if _backgroundSound then
|
||
for i = 1, #_backgroundSound do
|
||
local audioBg = _backgroundSound[i]
|
||
if audioBg then
|
||
audioBg.audio:Stop()
|
||
if audioBg.audio.clip then
|
||
poolManager:UnLoadAsset(audioBg.audio.clip.name,audioBg.audio.clip, PoolManager.AssetType.MediaUI)
|
||
audioBg.audio.clip = nil
|
||
end
|
||
end
|
||
end
|
||
end
|
||
|
||
if _AmbientChannel then
|
||
for i = 1, #_AmbientChannel do
|
||
local audioBg = _AmbientChannel[i]
|
||
if audioBg then
|
||
audioBg.audio:Stop()
|
||
if audioBg.audio.clip then
|
||
poolManager:UnLoadAsset(audioBg.audio.clip.name,audioBg.audio.clip, PoolManager.AssetType.MediaUI)
|
||
audioBg.audio.clip = nil
|
||
end
|
||
end
|
||
end
|
||
end
|
||
end
|
||
|
||
function SoundManager.Initialize()
|
||
SoundManager.Clear()
|
||
_node = GameObject("Sound Listener")
|
||
GameObject.DontDestroyOnLoad(_node)
|
||
|
||
for k, v in ConfigPairs(ConfigManager.GetConfig(ConfigName.AudioConfig)) do
|
||
AudioConfig[v.Name] = {
|
||
mixType = SoundDef[v.Type],
|
||
isLoop = v.Loop == 1
|
||
}
|
||
end
|
||
|
||
for i = 1, SoundManager.soundChannelCount do
|
||
local chanel = _node:AddComponent(typeof(AudioSource))
|
||
chanel.minDistance = 480
|
||
chanel.enabled = true
|
||
chanel.playOnAwake = false
|
||
chanel.loop = false
|
||
local audioUnit = {}
|
||
audioUnit.audio = chanel
|
||
audioUnit.audioType = eAudioType.uiAudio
|
||
audioUnit.isLock = false
|
||
table.insert(_soundChannel, audioUnit)
|
||
end
|
||
|
||
local _as = _node:AddComponent(typeof(AudioSource))
|
||
_as.minDistance = 480
|
||
_as.playOnAwake = false
|
||
_as.loop = false
|
||
local audioUnit = {}
|
||
audioUnit.audio = _as
|
||
audioUnit.audioType = eAudioType.bgAudio
|
||
audioUnit.isLock = false
|
||
table.insert(_backgroundSound, audioUnit)
|
||
|
||
local _am = _node:AddComponent(typeof(AudioSource))
|
||
_am.minDistance = 480
|
||
_am.playOnAwake = false
|
||
_am.loop = false
|
||
local audioUnit = {}
|
||
audioUnit.audio = _am
|
||
audioUnit.audioType = eAudioType.amAudio
|
||
audioUnit.isLock = false
|
||
table.insert(_AmbientChannel, audioUnit)
|
||
end
|
||
|
||
|
||
-- 外部改变音量大小
|
||
function SoundManager.ChangeSettingVolume(settingType, value)
|
||
if settingType == SETTING_TYPE.BGM_RATIO then
|
||
for _, unit in ipairs(_backgroundSound) do
|
||
unit.audio.volume = SoundManager.backgroundSoundVolume * value
|
||
end
|
||
elseif settingType == SETTING_TYPE.SOUND_RATIO then
|
||
for _, unit in ipairs(_soundChannel) do
|
||
unit.audio.volume = SoundManager.backgroundSoundVolume * value
|
||
end
|
||
for _, unit in ipairs(_AmbientChannel) do
|
||
unit.audio.volume = SoundManager.backgroundSoundVolume * value
|
||
end
|
||
end
|
||
end
|
||
|
||
-- 根据音效类型获取音效配置
|
||
local function GetAudioConfigByType(audioType)
|
||
if audioType == eAudioType.uiAudio then
|
||
return {volumeType = SETTING_TYPE.SOUND_RATIO, defaultVolume = 1}
|
||
elseif audioType == eAudioType.bgAudio then
|
||
return {volumeType = SETTING_TYPE.BGM_RATIO, defaultVolume = 1}
|
||
elseif audioType == eAudioType.amAudio then
|
||
return {volumeType = SETTING_TYPE.SOUND_RATIO, defaultVolume = 1}
|
||
end
|
||
end
|
||
|
||
--[[
|
||
clipName:音效资源名字
|
||
channel:固定音轨 nil:用空闲音轨播放
|
||
]]
|
||
local function setAudioMixer(clipName, audioUnit)
|
||
local config = AudioConfig[clipName]
|
||
if not config then
|
||
audioUnit.audio.loop = false
|
||
return
|
||
end
|
||
if config.mixType and audioUnit.mixType ~= config.mixType then
|
||
Util.SetAudioMixer(config.mixType, audioUnit.audio)
|
||
audioUnit.mixType = config.mixType
|
||
end
|
||
audioUnit.audio.loop = config.isLoop
|
||
end
|
||
|
||
|
||
-- 设置audioUnit
|
||
local function _SetAudioUnit(audioUnit, resName, auildType, volume)
|
||
__DebugLog("_SetAudioUnit -------->"..resName)
|
||
-- 获取声音文件
|
||
local clipNew = poolManager:LoadAsset(resName, PoolManager.AssetType.MediaBg)
|
||
if not clipNew then return nil end
|
||
-- 卸载旧音效
|
||
if audioUnit.audio.clip then
|
||
poolManager:UnLoadAsset(audioUnit.audio.clip.name,audioUnit.audio.clip, PoolManager.AssetType.MediaBg)
|
||
__DebugLog("卸载旧音效 -------->"..audioUnit.audio.clip.name)
|
||
audioUnit.audio.clip = nil
|
||
end
|
||
-- 获取类型配置
|
||
if not volume then
|
||
local audioTypeConfig = GetAudioConfigByType(auildType)
|
||
local ratio = SettingManager.GetSettingData(audioTypeConfig.volumeType)
|
||
volume = audioTypeConfig.defaultVolume * ratio
|
||
end
|
||
-- 是否循环
|
||
local config = AudioConfig[resName]
|
||
local isLoop = config and config.isLoop
|
||
|
||
local pitch = 1
|
||
if auildType == eAudioType.uiAudio then
|
||
if config and config.mixType == SoundDef[4] then
|
||
if UIManager.IsOpen(UIName.BattlePanel) then
|
||
local scale = BattleManager.GetTimeScale()
|
||
pitch = math.floor(scale + 0.5)
|
||
end
|
||
end
|
||
end
|
||
|
||
-- 播放新音效
|
||
if not config or config.mixType == SoundDef[1] or config.mixType == SoundDef[2] or isLoop then
|
||
audioUnit.audio.clip = clipNew
|
||
audioUnit.audio.volume = volume
|
||
audioUnit.audioType = auildType
|
||
audioUnit.audio.loop = isLoop
|
||
audioUnit.audio.pitch = pitch
|
||
audioUnit.audio:Play()
|
||
else
|
||
audioUnit.audio:PlayOneShot(clipNew, volume)
|
||
audioUnit.audio.pitch = pitch
|
||
end
|
||
setAudioMixer(resName, audioUnit)
|
||
end
|
||
|
||
local function _StopAudioUnit(audioUnit)
|
||
-- 卸载旧音效
|
||
if audioUnit.audio.clip then
|
||
poolManager:UnLoadAsset(audioUnit.audio.clip.name,audioUnit.audio.clip, PoolManager.AssetType.MediaBg)
|
||
__DebugLog("卸载旧音效 -------->"..audioUnit.audio.clip.name)
|
||
audioUnit.audio.clip = nil
|
||
end
|
||
audioUnit.audio:Stop()
|
||
end
|
||
|
||
local _FadeTime = 1
|
||
local function _FadeOutUnit(audioUnit, _FadeDone)
|
||
if not audioUnit then
|
||
if _FadeDone then _FadeDone() end
|
||
end
|
||
-- 声音淡出
|
||
DoTween.To(
|
||
DG.Tweening.Core.DOGetter_float( function () return audioUnit.audio.volume end),
|
||
DG.Tweening.Core.DOSetter_float(
|
||
function (progress)
|
||
audioUnit.audio.volume = progress
|
||
end),
|
||
0, _FadeTime)
|
||
:SetEase(Ease.Linear)
|
||
:OnComplete(
|
||
function ()
|
||
-- 淡出完成回调
|
||
_StopAudioUnit(audioUnit)
|
||
if _FadeDone then _FadeDone() end
|
||
end)
|
||
end
|
||
local function _FadeInUnit(audioUnit, auildType, _FadeDone)
|
||
if not audioUnit then
|
||
if _FadeDone then _FadeDone() end
|
||
end
|
||
-- 获取类型配置
|
||
local audioTypeConfig = GetAudioConfigByType(auildType)
|
||
-- 声音淡入
|
||
DoTween.To(
|
||
DG.Tweening.Core.DOGetter_float( function () return 0 end),
|
||
DG.Tweening.Core.DOSetter_float(function (progress)
|
||
local ratio = SettingManager.GetSettingData(audioTypeConfig.volumeType)
|
||
audioUnit.audio.volume = progress * ratio
|
||
end),
|
||
audioTypeConfig.defaultVolume, _FadeTime)
|
||
:SetEase(Ease.Linear)
|
||
:OnComplete(function()
|
||
-- 淡入完成回调
|
||
if _FadeDone then _FadeDone() end
|
||
end)
|
||
end
|
||
|
||
|
||
-- 切换音效
|
||
local function _ChangeAudio(outUnit, inUnit, resName, audioType, fadeType, runType, _FadeOutDone, _FadeInDone)
|
||
|
||
fadeType = fadeType or AUDIO_FADE_TYPE.DIRECT_CHANGE
|
||
runType = runType or AUDIO_RUN_TYPE.SEQ
|
||
|
||
if fadeType == AUDIO_FADE_TYPE.FADE_OUT_AND_IN then
|
||
if runType == AUDIO_RUN_TYPE.SEQ then
|
||
_FadeOutUnit(outUnit, function()
|
||
-- 淡出完成回调
|
||
_SetAudioUnit(inUnit, resName, audioType, 0)
|
||
if _FadeOutDone then _FadeOutDone() end
|
||
_FadeInUnit(inUnit, audioType, _FadeInDone)
|
||
end)
|
||
elseif runType == AUDIO_RUN_TYPE.CONC then
|
||
_FadeOutUnit(outUnit, _FadeOutDone)
|
||
_SetAudioUnit(inUnit, resName, audioType, 0)
|
||
_FadeInUnit(inUnit, audioType, _FadeInDone)
|
||
end
|
||
|
||
elseif fadeType == AUDIO_FADE_TYPE.FADE_OUT_NOT_IN then
|
||
if runType == AUDIO_RUN_TYPE.SEQ then
|
||
_FadeOutUnit(outUnit, function()
|
||
-- 淡出完成回调
|
||
_SetAudioUnit(inUnit, resName, audioType)
|
||
if _FadeOutDone then _FadeOutDone() end
|
||
if _FadeInDone then _FadeInDone() end
|
||
end)
|
||
elseif runType == AUDIO_RUN_TYPE.CONC then
|
||
_FadeOutUnit(outUnit, _FadeOutDone)
|
||
_SetAudioUnit(inUnit, resName, audioType)
|
||
if _FadeInDone then _FadeInDone() end
|
||
end
|
||
elseif fadeType == AUDIO_FADE_TYPE.FADE_IN_NOT_OUT then
|
||
-- 顺序,同步相同
|
||
_StopAudioUnit(outUnit)
|
||
_SetAudioUnit(inUnit, resName, audioType, 0)
|
||
if _FadeOutDone then _FadeOutDone() end
|
||
_FadeInUnit(inUnit, _FadeInDone)
|
||
elseif fadeType == AUDIO_FADE_TYPE.DIRECT_CHANGE then
|
||
_StopAudioUnit(outUnit)
|
||
_SetAudioUnit(inUnit, resName, audioType)
|
||
if _FadeOutDone then _FadeOutDone() end
|
||
if _FadeInDone then _FadeInDone() end
|
||
end
|
||
end
|
||
|
||
|
||
---- ==============================播放音效===================================
|
||
function SoundManager.PlaySound(clipName, fadeType, runType, channel, outChannel)
|
||
__DebugLog("*****")
|
||
-- 判断是否符合音效时间限制
|
||
if _AudioPlayList[clipName] then
|
||
local startTime = _AudioPlayList[clipName].startTime
|
||
local nowTime = Time.realtimeSinceStartup
|
||
if nowTime - startTime < _AudioPlayCD then
|
||
__DebugLog("与同名音效播放时间间隔小于cd时间被舍弃,音效:"..clipName)
|
||
return
|
||
end
|
||
end
|
||
|
||
local function _AddStartTime()
|
||
-- 记录音效播放时间点
|
||
_AudioPlayList[clipName] = {
|
||
startTime = Time.realtimeSinceStartup
|
||
}
|
||
end
|
||
|
||
--找一个空闲的音源播放
|
||
if not channel then
|
||
for i = 1, SoundManager.soundChannelCount do
|
||
local audioUnit = _soundChannel[i]
|
||
if not audioUnit.audio.isPlaying then
|
||
channel = i
|
||
break
|
||
end
|
||
end
|
||
end
|
||
if not channel then
|
||
Log("播放音效失败,超出了最大数量的限制,音效:"..clipName)
|
||
return
|
||
end
|
||
if not outChannel then
|
||
outChannel = channel
|
||
end
|
||
|
||
__DebugLog("播放音效-------->"..clipName.."channel ->"..channel.."outChannel ->"..outChannel)
|
||
local inUnit = _soundChannel[channel]
|
||
local outUnit = _soundChannel[outChannel]
|
||
_ChangeAudio(outUnit, inUnit, clipName, eAudioType.uiAudio, fadeType, runType, _AddStartTime)
|
||
|
||
return inUnit
|
||
end
|
||
|
||
-- 通过通道关闭音效
|
||
function SoundManager.StopSoundByChannel(channel)
|
||
local audioUnit = _soundChannel[channel]
|
||
_StopAudioUnit(audioUnit)
|
||
end
|
||
|
||
-- 关闭音效
|
||
function SoundManager.StopSound(audioUnit)
|
||
_StopAudioUnit(audioUnit)
|
||
end
|
||
|
||
--- =================================背景音======================================
|
||
local _MusicTimer = nil
|
||
function SoundManager.PlayMusic(resName, isFade, callback)
|
||
if resName == nil then return end
|
||
if resName == _backgroundRes then return end
|
||
|
||
if not _backgroundSound then return end
|
||
local audioUnit = _backgroundSound[1]
|
||
if not audioUnit then return end
|
||
|
||
_backgroundRes = resName
|
||
|
||
local function _SetTimer()
|
||
-- 关闭音乐计时器
|
||
if _MusicTimer then
|
||
_MusicTimer:Stop()
|
||
_MusicTimer = nil
|
||
end
|
||
if callback then
|
||
-- 获取声音文件
|
||
local config = AudioConfig[resName]
|
||
local isLoop = config and config.isLoop
|
||
_MusicTimer = Timer.New(callback, audioUnit.audio.clip.length, isLoop and -1 or 1, true)
|
||
_MusicTimer:Start()
|
||
end
|
||
end
|
||
local fadeType = AUDIO_FADE_TYPE.DIRECT_CHANGE
|
||
if isFade == nil or isFade then
|
||
fadeType = AUDIO_FADE_TYPE.FADE_OUT_AND_IN
|
||
end
|
||
_ChangeAudio(audioUnit, audioUnit, resName, eAudioType.bgAudio, fadeType, AUDIO_RUN_TYPE.SEQ, _SetTimer)
|
||
end
|
||
--暂停当前背景音乐
|
||
function SoundManager.StopMusic()
|
||
local audioUnit = _backgroundSound[1]
|
||
if audioUnit then
|
||
audioUnit.audio:Stop()
|
||
end
|
||
-- 关闭音乐计时器
|
||
if _MusicTimer then
|
||
_MusicTimer:Stop()
|
||
_MusicTimer = nil
|
||
end
|
||
_backgroundRes = nil
|
||
end
|
||
|
||
---=============================环境音效============================================
|
||
function SoundManager.PlayAmbient(resName)
|
||
if not resName then return end
|
||
-- 播放相同音效
|
||
if resName == _AmbientRes then return end
|
||
-- 通道检测
|
||
if not _AmbientChannel or not _AmbientChannel[1] then return end
|
||
|
||
local audioUnit = _AmbientChannel[1]
|
||
if not audioUnit then return end
|
||
|
||
_AmbientRes = resName
|
||
|
||
_ChangeAudio(audioUnit, audioUnit, resName, eAudioType.amAudio, AUDIO_FADE_TYPE.FADE_OUT_AND_IN, AUDIO_RUN_TYPE.SEQ)
|
||
end
|
||
--暂停当前背景音乐
|
||
function SoundManager.PauseAmbient()
|
||
local audioUnit = _AmbientChannel[1]
|
||
if audioUnit then
|
||
-- 声音淡出
|
||
DoTween.To(
|
||
DG.Tweening.Core.DOGetter_float( function () return audioUnit.audio.volume end),
|
||
DG.Tweening.Core.DOSetter_float(
|
||
function (progress)
|
||
audioUnit.audio.volume = progress
|
||
end),
|
||
0, 1)
|
||
:SetEase(Ease.Linear)
|
||
:OnComplete(function ()
|
||
audioUnit.audio:Pause()
|
||
end)
|
||
end
|
||
_AmbientRes = nil
|
||
end
|
||
|
||
|
||
--- ========================== 音效控制===========================
|
||
function SoundManager.GetSoundEnabled()
|
||
return _sfx_enabled
|
||
end
|
||
|
||
function SoundManager.SetSoundEnabled(b)
|
||
if _sfx_enabled == b then return end
|
||
_sfx_enabled = b
|
||
end
|
||
|
||
function SoundManager.GetBgmEnabled()
|
||
return _bgm_enabled
|
||
end
|
||
|
||
function SoundManager.SetBgmEnabled(b)
|
||
if _bgm_enabled == b then return end
|
||
_bgm_enabled = b
|
||
end
|
||
|
||
-- 设置音效播放速度
|
||
function SoundManager.SetAudioSpeed(speed)
|
||
speed = speed or 1
|
||
-- for _, unit in ipairs(_backgroundSound) do
|
||
-- unit.audio.pitch = speed
|
||
-- end
|
||
-- for _, unit in ipairs(_soundChannel) do
|
||
-- unit.audio.pitch = speed
|
||
-- end
|
||
-- for _, unit in ipairs(_AmbientChannel) do
|
||
-- unit.audio.pitch = speed
|
||
-- end
|
||
end
|
||
|
||
|
||
function SoundManager.Dispose()
|
||
SoundManager.Clear()
|
||
end
|
||
|
||
|
||
--endregion
|