Files
gold_dolphin/unity/Assets/UI/AudioManager.cs
T
2026-06-30 09:46:59 +08:00

125 lines
3.8 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace GameFramework
{
/// <summary>
/// 音频片段数据,可挂到 ScriptableObject 或直接 SerializeField。
/// </summary>
[System.Serializable]
public class AudioData
{
public AudioClip audioClip;
[Range(0f, 1f)] public float volume = 1f;
}
/// <summary>
/// 全局音频管理器(持久单例)。
/// 管理 BGM(背景音乐,循环)和 SFX(音效,一次性)。
/// 音量通过 PlayerPrefs 持久化。
/// </summary>
public class AudioManager : PersistentSingleton<AudioManager>
{
const string PREF_BGM_VOLUME = "AudioManager_BGMVolume";
const string PREF_SFX_VOLUME = "AudioManager_SFXVolume";
AudioSource bgmPlayer; // 背景音乐播放器
AudioSource sfxPlayer; // 音效播放器
float bgmVolume = 1f;
float sfxVolume = 1f;
public float BGMVolume => bgmVolume;
public float SFXVolume => sfxVolume;
protected override void Awake()
{
base.Awake();
// 如果是重复实例,base.Awake 已调用 Destroy,这里直接返回
if (Instance != this) return;
// 创建两个 AudioSource
bgmPlayer = gameObject.AddComponent<AudioSource>();
bgmPlayer.loop = true;
bgmPlayer.playOnAwake = false;
sfxPlayer = gameObject.AddComponent<AudioSource>();
sfxPlayer.loop = false;
sfxPlayer.playOnAwake = false;
// 读取持久化音量
bgmVolume = PlayerPrefs.GetFloat(PREF_BGM_VOLUME, 1f);
sfxVolume = PlayerPrefs.GetFloat(PREF_SFX_VOLUME, 1f);
bgmPlayer.volume = bgmVolume;
sfxPlayer.volume = sfxVolume;
}
#region BGM
/// <summary>
/// 播放背景音乐(循环)。
/// </summary>
public void PlayBGM(AudioClip clip, bool restart = false)
{
if (clip == null) return;
if (bgmPlayer.isPlaying && bgmPlayer.clip == clip && !restart)
return;
bgmPlayer.clip = clip;
bgmPlayer.volume = bgmVolume;
bgmPlayer.Play();
}
public void StopBGM()
{
if (bgmPlayer.isPlaying)
bgmPlayer.Stop();
}
public void PauseBGM() => bgmPlayer.Pause();
public void UnpauseBGM() => bgmPlayer.UnPause();
public void SetBGMVolume(float volume)
{
bgmVolume = Mathf.Clamp01(volume);
bgmPlayer.volume = bgmVolume;
PlayerPrefs.SetFloat(PREF_BGM_VOLUME, bgmVolume);
PlayerPrefs.Save();
}
#endregion
#region SFX
/// <summary>
/// 播放单个音效。
/// </summary>
public void PlaySFX(AudioData data)
{
if (data == null || data.audioClip == null) return;
// sfxPlayer.volume 已在 Awake 中设为 sfxVolume
// PlayOneShot 的 volumeScale 再乘以 data.volume
// 最终音量 = sfxVolume * data.volume
sfxPlayer.PlayOneShot(data.audioClip, data.volume);
}
/// <summary>
/// 从列表中随机播放一个音效。
/// </summary>
public void PlayRandomSFX(AudioData data, List<AudioData> variants = null)
{
if (variants != null && variants.Count > 0)
{
PlaySFX(variants[Random.Range(0, variants.Count)]);
return;
}
PlaySFX(data);
}
public void SetSFXVolume(float volume)
{
sfxVolume = Mathf.Clamp01(volume);
PlayerPrefs.SetFloat(PREF_SFX_VOLUME, sfxVolume);
PlayerPrefs.Save();
}
#endregion
}
}