c1_lua/lua/app/common/audio_manager.lua
2025-11-07 10:55:08 +08:00

300 lines
9.3 KiB
Lua

local AudioManager = {}
local BGM_VOLUME = 0.5
local MAX_EFFECT_NUM = 30
local AUDIO_CLIP = typeof(CS.UnityEngine.AudioClip)
AudioManager.BGM_ID = {
MAINCITY = "assets/arts/sounds/music/main_city.wav",
BATTLE = "assets/arts/sounds/music/battle.wav",
ACT_PVP_CHOOSEBGM = "assets/arts/sounds/music/act_pvp_choosebgm.wav",
ACT_PVP_FIGHT = "assets/arts/sounds/music/act_pvp_fight.wav",
ACT_PVP_MAINBGM = "assets/arts/sounds/music/act_pvp_mainbgm.wav",
}
AudioManager.CLICK_ID = {
[1] = "assets/arts/sounds/sfx/ui/ui_button.wav",
}
AudioManager.EFFECT_ID = {
BUTTON = "assets/arts/sounds/sfx/ui/ui_button.wav",
LINK_BO_1 = "assets/arts/sounds/sfx/battle/bo1.wav",
LINK_BO_2 = "assets/arts/sounds/sfx/battle/bo2.wav",
LINK_BO_3 = "assets/arts/sounds/sfx/battle/bo3.wav",
LINK_BO_4 = "assets/arts/sounds/sfx/battle/bo4.wav",
LINK_BO_5 = "assets/arts/sounds/sfx/battle/bo5.wav",
LINK_BO_6 = "assets/arts/sounds/sfx/battle/bo6.wav",
LINK_BO_7 = "assets/arts/sounds/sfx/battle/bo7.wav",
LINK_BO_8 = "assets/arts/sounds/sfx/battle/bo8.wav",
LINK_OVER = "assets/arts/sounds/sfx/battle/link_over.wav",
LINK_READY = "assets/arts/sounds/sfx/battle/link_ready.wav",
LINK_SKILL = "assets/arts/sounds/sfx/battle/link_skill.wav",
BATTLE_VICTORY = "assets/arts/sounds/sfx/ui/battle_victory.wav",
BATTLE_DEFEAT = "assets/arts/sounds/sfx/ui/battle_defeat.wav",
REWARD = "assets/arts/sounds/sfx/ui/reward.wav",
HERO_UP = "assets/arts/sounds/sfx/ui/hero_up.wav",
PLAYER_UP = "assets/arts/sounds/sfx/ui/player_up.wav",
BOSS_WARNING = "assets/arts/sounds/sfx/battle/warning_boss.wav",
LINK_CANCEL = "assets/arts/sounds/sfx/battle/link_cancel.wav",
FUNC_OPEN = "assets/arts/sounds/sfx/ui/func_open.wav",
BATTLE_BOX_OPEN = "assets/arts/sounds/sfx/ui/ui_battle_open_box.wav",
EQUIP_WEAPON_UP = "assets/arts/sounds/sfx/ui/equip_up.wav",
EQUIP_ARMOR_UP = "assets/arts/sounds/sfx/ui/armor_up.wav",
DUNGEON_SMASH = "assets/arts/sounds/sfx/ui/smash.wav",
STAR_GET = "assets/arts/sounds/sfx/ui/star_get.wav",
ACT_PVP_FINISH = "assets/arts/sounds/sfx/ui/act_pvp_finish.wav",
UI_SUMMON_START = "assets/arts/sounds/sfx/ui/summon_start.wav",
UI_SUMMON_RESULT_ONE = "assets/arts/sounds/sfx/ui/summon_result_one.wav",
UI_SUMMON_RESULT_TEN = "assets/arts/sounds/sfx/ui/summon_result_ten.wav",
UI_SUMMON_SHOW_HERO = "assets/arts/sounds/sfx/ui/summon_show_hero.wav",
UI_SUMMON_QLT_3 = "assets/arts/sounds/sfx/ui/summon_qlt_3.wav",
UI_SUMMON_QLT_4 = "assets/arts/sounds/sfx/ui/summon_qlt_4.wav",
UI_SUMMON_QLT_5 = "assets/arts/sounds/sfx/ui/summon_qlt_5.wav",
UI_SUMMON_QLT_6 = "assets/arts/sounds/sfx/ui/summon_qlt_6.wav",
}
AudioManager.BO_EFFECT_ID = {
[1] = AudioManager.EFFECT_ID.LINK_BO_1,
[2] = AudioManager.EFFECT_ID.LINK_BO_2,
[3] = AudioManager.EFFECT_ID.LINK_BO_3,
[4] = AudioManager.EFFECT_ID.LINK_BO_4,
[5] = AudioManager.EFFECT_ID.LINK_BO_5,
[6] = AudioManager.EFFECT_ID.LINK_BO_6,
[7] = AudioManager.EFFECT_ID.LINK_BO_7,
[8] = AudioManager.EFFECT_ID.LINK_BO_8,
}
AudioManager.EFFECT_PREFIX = "assets/arts/sounds/sfx/ui/%s.wav"
function AudioManager:getBoEffectID(index)
local id = AudioManager.BO_EFFECT_ID[index] or AudioManager.EFFECT_ID.LINK_BO_8
return id
end
function AudioManager:init()
self.musicEnabled = nil
self.effectEnabled = nil
self.musicVolume = 1
self.effectVolume = 1
self:setMusicVolume(LocalData:getAudioMusicVolume())
self:setEffectVolume(LocalData:getAudioEffectVolume())
self.audioSourcePool = {}
self.bgmAudioSource = nil
self.currentMusic = nil
end
function AudioManager:playMusic(audioPath, isLoop)
if audioPath == nil or audioPath == "" then
return
end
if not self.musicEnabled then
self.disableMusic = audioPath
self.disableMusicIsLoop = isLoop
return
end
if self.currentMusic == audioPath then
local as = self:getMusicSource()
if self.currentMusicIsLoop ~= isLoop then
if isLoop == nil then
as.loop = true
else
as.loop = isLoop
end
end
else
self.currentMusic = audioPath
self.currentMusicIsLoop = isLoop
if self.musicPath then
ResourceManager:unload(self.musicPath)
self.musicPath = nil
end
ResourceManager:loadOriginAssetAsync(audioPath, AUDIO_CLIP, function(path, audioClip)
if path == self.currentMusic then
self.musicPath = path
local as = self:getMusicSource()
as.clip = audioClip
if isLoop == nil then
isLoop = true
end
as.loop = isLoop
as:Play()
else
ResourceManager:unload(path)
end
end)
end
end
function AudioManager:stopMusicById(id, isClear)
if self.currentMusic == id then
self:stopMusic(isClear)
end
end
function AudioManager:stopMusic(isClear)
local bgmAudioSource = self:getMusicSource()
if bgmAudioSource then
bgmAudioSource:Stop()
if isClear then
bgmAudioSource.clip = nil
if self.musicPath then
ResourceManager:unload(self.musicPath)
self.musicPath = nil
end
self.currentMusic = nil
end
end
end
function AudioManager:pauseMusic()
local bgmAudioSource = self:getMusicSource()
if bgmAudioSource then
bgmAudioSource:Pause()
end
end
function AudioManager:resumeMusic()
local bgmAudioSource = self:getMusicSource()
if bgmAudioSource then
bgmAudioSource:UnPause()
end
end
function AudioManager:getAudioSourceFromPool(path)
local audioObj
for i, v in ipairs(self.audioSourcePool) do
if not v.audioSource.isPlaying then
audioObj = v
if v.path and v.path ~= path then
ResourceManager:unload(v.path)
v.path = path
end
break
end
end
if not audioObj and #self.audioSourcePool < MAX_EFFECT_NUM then
local audioSource = CS.BF.BFMain.Instance.SoundManager:addEffectAudioSource()
audioObj = {
path = path,
audioSource = audioSource
}
table.insert(self.audioSourcePool, audioObj)
end
return audioObj
end
function AudioManager:getMusicSource()
if not self.bgmAudioSource then
self.bgmAudioSource = CS.BF.BFMain.Instance.SoundManager:getMusicAudioSource()
end
self.bgmAudioSource.volume = self.musicVolume
return self.bgmAudioSource
end
function AudioManager:playEffect(audioPath, volume)
if audioPath == nil or audioPath == "" then
return
end
if not self.effectEnabled then
return
end
if volume then
volume = volume*self.effectVolume
else
volume = self.effectVolume
end
ResourceManager:loadOriginAssetAsync(audioPath, AUDIO_CLIP, function(path, audioClip)
if audioClip then
local asObj = self:getAudioSourceFromPool(path)
if asObj then
local audioSource = asObj.audioSource
audioSource.clip = audioClip
audioSource.loop = false
audioSource.volume = volume
audioSource:Play()
end
end
end)
end
function AudioManager:stopEffect(path)
for i, v in ipairs(self.audioSourcePool) do
if v.path and v.path == path then
v.audioSource:Stop()
end
end
end
function AudioManager:isMusicEnabled()
return self.musicEnabled
end
function AudioManager:isEffectEnabled()
return self.effectEnabled
end
function AudioManager:setMusicVolume(value)
self.musicVolume = value or 1
LocalData:setAudioMusicVolume(self.musicVolume)
self.musicEnabled = self.musicVolume > 0
if self.musicEnabled then
self:getMusicSource()
if self.disableMusic and self.disableMusic ~= "" then
self:playMusic(self.disableMusic, self.disableMusicIsLoop)
end
else
if self.currentMusic and self.currentMusic ~= "" then
self.disableMusic = self.currentMusic
self.disableMusicIsLoop = self.currentMusicIsLoop
end
self:stopMusic(true)
end
end
function AudioManager:getMusicVolume()
return self.musicVolume
end
function AudioManager:setEffectVolume(value)
self.effectVolume = value or 1
LocalData:setAudioEffectVolume(self.effectVolume)
self.effectEnabled = self.effectVolume > 0
if not self.effectEnabled then
self:stopAndClearAudioFx()
end
end
function AudioManager:getEffectVolume()
return self.effectVolume
end
function AudioManager:stopAndClearAudioFx()
if self.audioSourcePool then
for i, v in ipairs(self.audioSourcePool) do
v.audioSource:Stop()
if v.audioSource.clip then
v.audioSource.clip = nil
if v.path then
ResourceManager:unload(v.path)
v.path = nil
end
end
end
end
end
function AudioManager:clear()
self:stopMusic(true)
self:stopAndClearAudioFx()
self.bgmAudioSource = nil
self.audioSourcePool = nil
CS.BF.BFMain.Instance.SoundManager:clearAudioSource()
end
return AudioManager