221 lines
7.1 KiB
C#
221 lines
7.1 KiB
C#
using System.Collections;
|
||
using System.Collections.Generic;
|
||
using UnityEngine;
|
||
using UnityEngine.Audio;
|
||
|
||
public enum AudioType
|
||
{
|
||
None,
|
||
BG,
|
||
FX,
|
||
|
||
}
|
||
public class AudioManager : MonoSingleton<AudioManager>
|
||
{
|
||
Dictionary<AudioType,AudioSource> dic_audioList=new Dictionary<AudioType, AudioSource> ();
|
||
public AudioMixer audioMixer;
|
||
|
||
// ⭐ 音频资源字典由热更侧 AudioResourcesData 在加载/卸载时写入、重建。
|
||
// 放在框架层是为了让 AudioManager 不反向依赖热更类型(程序集解耦)。
|
||
/// <summary>音效ID → AudioClip(默认音频 + 当前玩法音频)</summary>
|
||
public static Dictionary<int, AudioClip> ClipDic = new Dictionary<int, AudioClip>();
|
||
/// <summary>音效资源名 → 音效ID(tbaudio.json 映射)</summary>
|
||
public static Dictionary<string, int> NameToIdDic = new Dictionary<string, int>();
|
||
|
||
/// <summary>该音效ID是否已有对应 AudioClip</summary>
|
||
public bool HasClip(int audioID)
|
||
{
|
||
return ClipDic != null && ClipDic.ContainsKey(audioID);
|
||
}
|
||
|
||
protected override void Awake()
|
||
{
|
||
base.Awake();
|
||
var v = UIManager.Instance.transform.GetChild(0).GetComponents<AudioSource>();
|
||
dic_audioList.Add(AudioType.BG, v[0]);
|
||
v[0].outputAudioMixerGroup = audioMixer.FindMatchingGroups("BG")[0];
|
||
dic_audioList.Add(AudioType.FX, v[1]);
|
||
v[1].outputAudioMixerGroup = audioMixer.FindMatchingGroups("FX")[0];
|
||
|
||
int a = PlayerPrefs.GetInt("first");
|
||
if (a==0)
|
||
{
|
||
PlayerPrefs.SetFloat("slider_AudioBG",1f);
|
||
PlayerPrefs.SetFloat("slider_FX", 1f);
|
||
PlayerPrefs.SetInt("first",1);
|
||
|
||
}
|
||
float value = PlayerPrefs.GetFloat("slider_AudioBG");
|
||
audioMixer.SetFloat("BGVolume", 20.0f * Mathf.Log10(Mathf.Max(value, 0.0001f)));
|
||
|
||
value = PlayerPrefs.GetFloat("slider_FX");
|
||
audioMixer.SetFloat("FXVolume", 20.0f * Mathf.Log10(Mathf.Max(value, 0.0001f)));
|
||
dic_audioList[AudioType.BG].outputAudioMixerGroup = audioMixer.FindMatchingGroups("Master/BG")[0];
|
||
dic_audioList[AudioType.FX].outputAudioMixerGroup = audioMixer.FindMatchingGroups("Master/FX")[0];
|
||
}
|
||
public AudioSource GetAudioSource(AudioType audioType)
|
||
{
|
||
if (dic_audioList.ContainsKey(audioType))
|
||
{
|
||
return dic_audioList[audioType];
|
||
}
|
||
else
|
||
return null;
|
||
|
||
}
|
||
public void StopBG()
|
||
{
|
||
AudioType audioType = AudioType.BG;
|
||
if (dic_audioList.ContainsKey(audioType))
|
||
{
|
||
dic_audioList[audioType].Stop();
|
||
|
||
}
|
||
}
|
||
public void ChangeBG(int audioID)
|
||
{
|
||
if (audioID == 0)
|
||
return;
|
||
if (ClipDic.ContainsKey(audioID))
|
||
{
|
||
|
||
AudioClip audioClip = ClipDic[audioID];
|
||
AudioType audioType = AudioType.BG;
|
||
if (dic_audioList.ContainsKey(audioType))
|
||
{
|
||
dic_audioList[audioType].clip = audioClip;
|
||
dic_audioList[audioType].Play();
|
||
|
||
}
|
||
}
|
||
else
|
||
{
|
||
//UIManager.Instance.ShowBoardError("未找到"+audioID);
|
||
Debug.LogError("未找到音频ID: " + audioID);
|
||
}
|
||
|
||
}
|
||
public void ChangeBG(AudioClip audioClip)
|
||
{
|
||
AudioType audioType=AudioType.BG;
|
||
if (dic_audioList.ContainsKey(audioType))
|
||
{
|
||
dic_audioList[audioType].clip = audioClip;
|
||
dic_audioList[audioType].Play();
|
||
|
||
}
|
||
}
|
||
public void PlayerFX(int audioID)
|
||
{
|
||
if (audioID == 0)
|
||
return;
|
||
if (ClipDic.ContainsKey(audioID))
|
||
{
|
||
|
||
AudioClip audioClip = ClipDic[audioID];
|
||
AudioType audioType = AudioType.FX;
|
||
if (dic_audioList.ContainsKey(audioType))
|
||
{
|
||
dic_audioList[audioType].PlayOneShot(audioClip);
|
||
|
||
}
|
||
}
|
||
else
|
||
{
|
||
//UIManager.Instance.ShowBoardError("未找到"+audioID);
|
||
Debug.LogError("未找到音频ID: " + audioID);
|
||
}
|
||
|
||
}
|
||
public void PlayFX(AudioClip audioClip)
|
||
{
|
||
AudioType audioType = AudioType.FX;
|
||
if (dic_audioList.ContainsKey(audioType))
|
||
{
|
||
dic_audioList[audioType].PlayOneShot(audioClip);
|
||
|
||
}
|
||
}
|
||
|
||
private AudioSource _fxLoopSource;
|
||
|
||
/// <summary>
|
||
/// 循环音效专用 AudioSource(懒创建,与 FX 共用混音组)。
|
||
/// ⭐ 单独一条 source:Stop 只停循环音效,不会误杀 PlayOneShot 的一次性音效。
|
||
/// </summary>
|
||
private AudioSource GetFxLoopSource()
|
||
{
|
||
if (_fxLoopSource == null)
|
||
{
|
||
var fx = GetAudioSource(AudioType.FX);
|
||
GameObject host = fx != null ? fx.gameObject : UIManager.Instance.transform.GetChild(0).gameObject;
|
||
_fxLoopSource = host.AddComponent<AudioSource>();
|
||
_fxLoopSource.playOnAwake = false;
|
||
_fxLoopSource.loop = true;
|
||
if (fx != null) _fxLoopSource.outputAudioMixerGroup = fx.outputAudioMixerGroup;
|
||
}
|
||
return _fxLoopSource;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 循环播放音效(如战神激光长音频)。重复调用同一条 clip 且已在播时不重头播放,只更新播放速度,
|
||
/// ⭐ 长音频用它代替逐发 PlayOneShot,避免声音重叠;pitch=2 即 2 倍速(狂暴)。
|
||
/// </summary>
|
||
public void PlayFXLoop(AudioClip audioClip, float pitch = 1f)
|
||
{
|
||
if (audioClip == null) return;
|
||
var src = GetFxLoopSource();
|
||
src.pitch = pitch > 0f ? pitch : 1f;
|
||
if (src.clip == audioClip && src.isPlaying) return; // 同一条音效已在循环 → 只变速,不重播
|
||
src.clip = audioClip;
|
||
src.loop = true;
|
||
src.Play();
|
||
}
|
||
|
||
/// <summary>停止循环音效(不影响 PlayOneShot 的一次性音效)</summary>
|
||
public void StopFXLoop()
|
||
{
|
||
if (_fxLoopSource != null && _fxLoopSource.isPlaying)
|
||
_fxLoopSource.Stop();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 按音效资源名(#Audio 表 AudioResourcesPath,如 PW_Shark_Show)播放音效。
|
||
/// 名字 → ID 走 tbaudio.json 映射,表 ID 调整时无需改代码。
|
||
/// </summary>
|
||
public void PlayerFXByName(string audioName)
|
||
{
|
||
if (string.IsNullOrEmpty(audioName)) return;
|
||
if (NameToIdDic != null && NameToIdDic.TryGetValue(audioName, out int audioID))
|
||
{
|
||
PlayerFX(audioID);
|
||
}
|
||
else
|
||
{
|
||
Debug.LogWarning("未找到音频资源名: " + audioName);
|
||
}
|
||
}
|
||
public bool UpdateAudioClip(AudioType audioType,AudioClip audioClip)
|
||
{
|
||
if (dic_audioList.ContainsKey(audioType))
|
||
{
|
||
dic_audioList[audioType].clip=audioClip;
|
||
dic_audioList[audioType].Play();
|
||
return true;
|
||
}
|
||
else
|
||
return false;
|
||
}
|
||
|
||
public bool PlayOneShot(AudioType audioType, AudioClip audioClip)
|
||
{
|
||
if (dic_audioList.ContainsKey(audioType))
|
||
{
|
||
dic_audioList[audioType].PlayOneShot(audioClip);
|
||
return true;
|
||
}
|
||
else
|
||
return false;
|
||
}
|
||
}
|