添加场景、对应场景代码
This commit is contained in:
@@ -0,0 +1,124 @@
|
||||
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
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user