Unity加载本地音乐/声音(异步加载)
using UnityEngine; using UnityEngine.Networking; using System.Collections; using System.Collections.Generic; //内存占用 ≈ 时长(秒) × 采样率(Hz) × 声道数 × 2字节 //3 分钟(180 秒)、44100Hz、立体声(2 声道): //180 × 44100 × 2 × 2 ≈ 63 MB /// <summary> /// 音乐管理器:负责加载、缓存和播放背景音乐。 /// 使用 StreamingAssets 文件夹中的音频文件。 /// </summary> public class SoundManager : MonoBehaviour { /// <summary> /// 全局单例实例 /// </summary> public static SoundManager Instance { get; private set; } /// <summary> /// 播放音乐的 AudioSource 组件 /// </summary> private AudioSource _audioSource; /// <summary> /// 音乐缓存字典,避免重复加载 /// </summary> private readonly Dictionary<string, AudioClip> _musicCache = new(); /// <summary> /// 播放顺序队列,用于控制缓存数量 /// </summary> private readonly Queue<string> _playHistory = new(); [Header("缓存设置")] [Tooltip("允许缓存的最大歌曲数量")] public int MaxCacheCount = 5; /// <summary> /// 当前正在播放的音乐文件名 /// </summary> private string _currentTrack; private void Awake() { if (Instance != null) { Destroy(gameObject); return; } Instance = this; DontDestroyOnLoad(gameObject); _audioSource = gameObject.AddComponent<AudioSource>(); } /// <summary> /// 播放指定文件名的音乐(避免重复播放同一首) /// </summary> /// <param name="fileName">音频文件名(需放置在 StreamingAssets 文件夹中)</param> public void Play(string fileName) { // 如果当前正在播放相同的曲目,忽略此次请求 if (_currentTrack == fileName && _audioSource.isPlaying) return; if (_musicCache.TryGetValue(fileName, out var clip)) { _audioSource.clip = clip; _audioSource.Play(); _currentTrack = fileName; } else { StartCoroutine(LoadAndPlay(fileName)); } } /// <summary> /// 从 StreamingAssets 异步加载音乐并播放,同时管理缓存 /// </summary> private IEnumerator LoadAndPlay(string fileName) { string path = System.IO.Path.Combine(Application.streamingAssetsPath, fileName); using UnityWebRequest request = UnityWebRequestMultimedia.GetAudioClip(path, AudioType.MPEG); yield return request.SendWebRequest(); if (request.result != UnityWebRequest.Result.Success) { Debug.LogError($"音乐加载失败: {request.error}"); yield break; } AudioClip clip = DownloadHandlerAudioClip.GetContent(request); // 加入缓存(仅当未缓存时) if (!_musicCache.ContainsKey(fileName)) { _musicCache[fileName] = clip; _playHistory.Enqueue(fileName); // 缓存超过上限时,移除最早播放的音乐 if (_playHistory.Count > MaxCacheCount) { string oldest = _playHistory.Dequeue(); if (_musicCache.ContainsKey(oldest)) { Destroy(_musicCache[oldest]); _musicCache.Remove(oldest); } } } _audioSource.clip = clip; _audioSource.Play(); _currentTrack = fileName; } }
posted on 2025-08-16 23:44 zqiang0803 阅读(82) 评论(0) 收藏 举报
浙公网安备 33010602011771号