using UnityEngine; /// /// 统一音频管理器——挂在 [Managers] 上,管理所有背景音乐/音效/语音。 /// 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(); _bgSource.loop = true; _bgSource.playOnAwake = false; _bgSource.spatialBlend = 0f; _sfxSource = gameObject.AddComponent(); _sfxSource.playOnAwake = false; _sfxSource.spatialBlend = 0f; _voiceSource = gameObject.AddComponent(); _voiceSource.playOnAwake = false; _voiceSource.spatialBlend = 0f; #if UNITY_EDITOR if (_homeBg == null) _homeBg = UnityEditor.AssetDatabase.LoadAssetAtPath("Assets/Audio/homeBackgroundMusic.mp3"); if (_experimentBg == null) _experimentBg = UnityEditor.AssetDatabase.LoadAssetAtPath("Assets/Audio/backgroundMusic.mp3"); if (_basketballSfx == null) _basketballSfx = UnityEditor.AssetDatabase.LoadAssetAtPath("Assets/Audio/start/basketballSound.wav"); if (_manCallSfx == null) _manCallSfx = UnityEditor.AssetDatabase.LoadAssetAtPath("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 SwitchToCamera3() { StartCoroutine(SmoothSwitchCameraCoroutine()); } private System.Collections.IEnumerator SmoothSwitchCameraCoroutine() { var cam2 = GameObject.Find("camera2"); var cam3 = GameObject.Find("camera3"); if (cam2 == null || cam3 == null) { if (cam2 != null) { var c = cam2.GetComponent(); if (c != null) c.enabled = false; } if (cam3 != null) { var c = cam3.GetComponent(); if (c != null) c.enabled = true; } yield break; } var c2 = cam2.GetComponent(); var c3 = cam3.GetComponent(); if (c2 == null || c3 == null) yield break; // 保存 camera3 原本的目标位置和旋转 Vector3 targetPos = cam3.transform.position; Quaternion targetRot = cam3.transform.rotation; // 将 camera3 放到 camera2 的位置 cam3.transform.position = cam2.transform.position; cam3.transform.rotation = cam2.transform.rotation; // 切换激活状态,这样任何挂在 camera3 上的后期特效立刻生效,但视角还没变 c2.enabled = false; c3.enabled = true; // 在这里把 woman 的 IsCheck 设为 true var woman = GameObject.Find("woman"); if (woman != null) { var anim = woman.GetComponent(); if (anim != null) anim.SetBool("IsCheck", true); } float duration = 1.0f; float elapsed = 0f; while (elapsed < duration) { elapsed += Time.deltaTime; float t = elapsed / duration; // 加上平滑曲线 (EaseInOut) t = t * t * (3f - 2f * t); cam3.transform.position = Vector3.Lerp(cam2.transform.position, targetPos, t); cam3.transform.rotation = Quaternion.Slerp(cam2.transform.rotation, targetRot, t); yield return null; } cam3.transform.position = targetPos; cam3.transform.rotation = targetRot; Debug.Log("[AudioManager] camera2→camera3 平滑过渡完成"); } }