Files
VFSUnity/Assets/Scripts/Audio/AudioManager.cs
T

145 lines
4.8 KiB
C#
Raw Normal View History

using UnityEngine;
/// <summary>
/// 统一音频管理器——挂在 [Managers] 上,管理所有背景音乐/音效/语音。
/// </summary>
public class AudioManager : MonoBehaviour
{
public static AudioManager I { get; private set; }
[Header("背景音乐")]
[SerializeField] private AudioClip _homeBg;
[SerializeField] private AudioClip _experimentBg;
[Range(0,1)] public float BgVolume = 0.5f;
[Header("音效")]
[SerializeField] private AudioClip _basketballSfx;
[SerializeField] private AudioClip _manCallSfx;
private AudioSource _bgSource;
private AudioSource _sfxSource;
private AudioSource _voiceSource;
void Awake()
{
I = this;
_bgSource = gameObject.AddComponent<AudioSource>();
_bgSource.loop = true;
_bgSource.playOnAwake = false;
_bgSource.spatialBlend = 0f;
_sfxSource = gameObject.AddComponent<AudioSource>();
_sfxSource.playOnAwake = false;
_sfxSource.spatialBlend = 0f;
_voiceSource = gameObject.AddComponent<AudioSource>();
_voiceSource.playOnAwake = false;
_voiceSource.spatialBlend = 0f;
#if UNITY_EDITOR
if (_homeBg == null) _homeBg = UnityEditor.AssetDatabase.LoadAssetAtPath<AudioClip>("Assets/Audio/homeBackgroundMusic.mp3");
if (_experimentBg == null) _experimentBg = UnityEditor.AssetDatabase.LoadAssetAtPath<AudioClip>("Assets/Audio/backgroundMusic.mp3");
if (_basketballSfx == null) _basketballSfx = UnityEditor.AssetDatabase.LoadAssetAtPath<AudioClip>("Assets/Audio/start/basketballSound.wav");
if (_manCallSfx == null) _manCallSfx = UnityEditor.AssetDatabase.LoadAssetAtPath<AudioClip>("Assets/Audio/start/mancall.wav");
#endif
Debug.Log($"[AudioManager] 就绪 homeBg={_homeBg!=null} expBg={_experimentBg!=null} sfx={_basketballSfx!=null}/{_manCallSfx!=null}");
}
// ────── 背景音乐 ──────
public void PlayHomeBg()
{
if (_homeBg == null) return;
_bgSource.clip = _homeBg;
_bgSource.volume = BgVolume;
_bgSource.Play();
Debug.Log($"[AudioManager] 首页bg isPlaying={_bgSource.isPlaying}");
}
public void PlayExperimentBg()
{
if (_experimentBg == null) return;
_bgSource.clip = _experimentBg;
_bgSource.volume = BgVolume;
_bgSource.Play();
Debug.Log($"[AudioManager] 实验bg isPlaying={_bgSource.isPlaying}");
}
public void StopBgMusic()
{
_bgSource.Stop();
Debug.Log("[AudioManager] 停止bg");
}
// ────── 音效(可打断) ──────
public void PlaySfx(AudioClip clip)
{
if (clip == null) return;
_sfxSource.Stop();
_sfxSource.clip = clip;
_sfxSource.Play();
}
public void StopSfx() { _sfxSource.Stop(); }
public void PlayBasketballSfx() => PlaySfx(_basketballSfx);
public void PlayManCallSfx() => PlaySfx(_manCallSfx);
// ────── 语音(可打断) ──────
public void PlayVoice(AudioClip clip)
{
if (clip == null) return;
_voiceSource.Stop();
_voiceSource.clip = clip;
_voiceSource.Play();
Debug.Log($"[AudioManager] 播放语音: {clip.name}");
}
public void StopVoice() { _voiceSource.Stop(); }
public void SwitchToCamera3Smooth()
{
StartCoroutine(Camera3SwitchRoutine());
}
System.Collections.IEnumerator Camera3SwitchRoutine()
{
var black = GameObject.Find("BlackScreenPanel");
var blackImg = black != null ? black.GetComponent<UnityEngine.UI.Image>() : null;
float duration = 0.8f;
// 渐入黑
if (black != null && blackImg != null)
{
black.SetActive(true);
for (float t = 0f; t < duration; t += Time.deltaTime)
{
blackImg.color = new Color(0, 0, 0, t / duration);
yield return null;
}
blackImg.color = Color.black;
}
// 切换摄像机
var cam2 = GameObject.Find("camera2");
var cam3 = GameObject.Find("camera3");
if (cam2 != null) { var c = cam2.GetComponent<Camera>(); if (c != null) c.enabled = false; }
if (cam3 != null) { var c = cam3.GetComponent<Camera>(); if (c != null) c.enabled = true; }
Debug.Log("[AudioManager] camera2→camera3 平滑切换完成");
yield return new WaitForSeconds(0.2f);
// 渐出黑
if (black != null && blackImg != null)
{
for (float t = 0f; t < duration; t += Time.deltaTime)
{
blackImg.color = new Color(0, 0, 0, 1f - t / duration);
yield return null;
}
blackImg.color = new Color(0, 0, 0, 0);
black.SetActive(false);
}
}
}