163 lines
5.5 KiB
C#
163 lines
5.5 KiB
C#
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 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<Camera>(); if (c != null) c.enabled = false; }
|
|
if (cam3 != null) { var c = cam3.GetComponent<Camera>(); if (c != null) c.enabled = true; }
|
|
yield break;
|
|
}
|
|
|
|
var c2 = cam2.GetComponent<Camera>();
|
|
var c3 = cam3.GetComponent<Camera>();
|
|
|
|
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<Animator>();
|
|
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 平滑过渡完成");
|
|
}
|
|
}
|