Unity组件开发--背景音乐管理器

news/2024/5/18 15:39:13 标签: unity, 游戏引擎, 游戏程序

1.背景音乐作为一个独立的节点:

2.通过Url加载背景音乐:运行后添加AudioSource组件

using DG.Tweening;
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Analytics;
using UnityEngine.Networking;

public class PlaySceneBgm : MonoBehaviour
{
    [HideInInspector]
    public AudioSource audioS;
    [HideInInspector]
    public string url;
    [HideInInspector]
    public static PlaySceneBgm Instance;
    private bool isLoaded;
    // Start is called before the first frame update
    [HideInInspector]
    public string defaultbgmUrl = "";

    private float playCurMusicProgress = 0;
    private bool isPaused = false;
    private string lastPlayUrl = "";
    public void SetUrl(string audioLink)
    {

        if (url == audioLink)
        {
            return;
        }
        this.playCurMusicProgress = 0;
        url = audioLink;
        StartCoroutine(GetAudioClip(true));
    }


    
    // Start is called before the first frame update
    void Awake()
    {

        audioS = gameObject.AddComponent<AudioSource>();
        audioS.playOnAwake = false;
        audioS.loop = true;
        audioS.volume = 0.25f;
        Instance = this;

        EventManager.Instance.AddListener(EventName.OnSceneLoaded, (s, e) => {
            if (!string.ReferenceEquals(PlayerData.Instance.TemplateId.ToString(), null))
            {

                url = "..........";
            }
            defaultbgmUrl = url;
            if (PlayerData.Instance.isRunningPC)
            {
                Debug.Log("当前是在PC上播放背景音乐");
                StartCoroutine(GetAudioClip(true));
            }
            
        });
        
        EventManager.Instance.AddListener(EventName.stopSceneBgm, stopSceneBgm);
        EventManager.Instance.AddListener(EventName.playSceneBgm, playSceneBgm);
        EventManager.Instance.AddListener(EventName.changeSceneBgmValue, changeSceneBgmValue);
    }



    public float getCurMusicPro() {

        return this.playCurMusicProgress;
    }

    public void stopSceneBgm(object sender, EventArgs e) {
        if (isLoaded && audioS.clip != null)
        {
            audioS.Pause();
            
            isPaused = true;
        }
    }

    public bool getPlayState() {

        if (isLoaded && audioS.clip != null)
        {
            return audioS.isPlaying;
        }
        else {

            return false;
        }
    }

    public void playSceneBgm(object sender, EventArgs e)
    {
        if (isLoaded && audioS.clip != null)
        {

            audioS.Play();
        }
        else {

            StartCoroutine(GetAudioClip(true));
        }
    }

    // 恢复音频播放
    public void resumeSceneBgm()
    {
        if (isLoaded && audioS.clip != null)
        {
            
            if (isPaused)
            {
                
                StartCoroutine(ResumeWithDelay());
                //url = lastPlayUrl;
                //StartCoroutine(GetAudioClip(true));
                isPaused = false;
            }
        }
        
    }

    private IEnumerator ResumeWithDelay()
    {
        yield return new WaitForSeconds(0.1f); // 添加 0.1 秒的延迟
        if (isLoaded && audioS.clip != null)
        {
            audioS.UnPause();
        }
            
    }

    public void changeSceneBgmValue(object sender, EventArgs e)
    {
        var data = e as changeBgmVolume;
        if (data != null) {

            audioS.volume = data.volume;
        }
    }

    IEnumerator GetAudioClip(bool isPlay = false)
    {
        this.playCurMusicProgress = 0;
        Debug.Log("音频加载11111" + url);
        if (UtilsFunc.IsURL(url) == false)
        {
            yield break;
        }

        var audioType = AudioType.MPEG;
        if (UtilsFunc.UrlExtension(url, "*.mp3") || UtilsFunc.UrlExtension(url, "*.MP3"))
        {
            audioType = AudioType.MPEG;
        }
        else if (UtilsFunc.UrlExtension(url, "*.wav"))
        {
            audioType = AudioType.WAV;
        }
        else if (UtilsFunc.UrlExtension(url, "*.ogg"))
        {
            audioType = AudioType.OGGVORBIS;
        }

        Debug.Log("音频加载0000" + url);
        //using (var uwr = UnityWebRequestMultimedia.GetAudioClip(url, audioType))
        //{
        //    yield return uwr.SendWebRequest();
        //    if (uwr.result != UnityWebRequest.Result.Success)
        //    {
        //        Debug.LogError("音频加载8888"+uwr.error);
        //        yield break;
        //    }
        //    Debug.Log("音频加载22222" + url);
        //    isLoaded = true;
        //    AudioClip clip = DownloadHandlerAudioClip.GetContent(uwr);
        //    // use audio clip
        //    // 在异步线程中进行加载和分配
        //    audioS.clip = clip;
        //    lastPlayUrl = url;
        //    StartCoroutine(LoadAudioClip(isPlay));    
        //}
        WWW _www = new WWW(url);
        yield return _www;
        if (_www.error == null)
        {
            isLoaded = true;
            AudioClip _audioClip = _www.GetAudioClip(true, true, audioType);
            audioS.clip = _audioClip;
            lastPlayUrl = url;
            StartCoroutine(LoadAudioClip(isPlay));    
        }
        else
        {
            Debug.Log(_www.error);
            Debug.LogError("音频加载报错" + _www.error);
            yield break;
        }

    }



    public void WebRequestPlayMP3()
    {
        
        StartCoroutine(IELoadExternalAudioWebRequest(url, AudioType.MPEG));
    }
    public void WWWPlayMP3()
    {
        
        StartCoroutine(IELoadExternalAudioWWW(url, AudioType.MPEG));
    }
    public void WebRequestPlayWAV()
    {
        
        StartCoroutine(IELoadExternalAudioWebRequest(url, AudioType.WAV));
    }
    public void WWWPlayWAV()
    {
        
        StartCoroutine(IELoadExternalAudioWWW(url, AudioType.WAV));
    }

    private IEnumerator IELoadExternalAudioWebRequest(string _url, AudioType _audioType)
    {
        UnityWebRequest _unityWebRequest = UnityWebRequestMultimedia.GetAudioClip(_url, _audioType);
        yield return _unityWebRequest.SendWebRequest();
        if (_unityWebRequest.isHttpError || _unityWebRequest.isNetworkError)
        {
            Debug.Log(_unityWebRequest.error.ToString());
        }
        else
        {
            AudioClip _audioClip = DownloadHandlerAudioClip.GetContent(_unityWebRequest);
            audioS.clip = _audioClip;
            audioS.Play();
        }
    }

    private IEnumerator IELoadExternalAudioWWW(string _url, AudioType _audioType)
    {

        this.playCurMusicProgress = 0;
        Debug.Log("音频加载11111" + url);
        if (UtilsFunc.IsURL(url) == false)
        {
            yield break;
        }

        WWW _www = new WWW(_url);
        yield return _www;
        if (_www.error == null)
        {
            AudioClip _audioClip = _www.GetAudioClip(true, true, _audioType);
            audioS.clip = _audioClip;
            audioS.Play();
        }
        else
        {
            Debug.Log(_www.error);
        }
    }


    private IEnumerator LoadAudioClip(bool isPlay = false)
    {

        yield return audioS.clip.LoadAudioData();
        yield return new WaitUntil(() => audioS.clip.loadState == AudioDataLoadState.Loaded);
        Debug.Log("音频加载状态......." + audioS.clip.loadState);
        if (isPlay && audioS.clip.loadState == AudioDataLoadState.Loaded)
        {
            audioS.Play();
        }

        
    }

    // Update is called once per frame
    void Update()
    {
        if (audioS.clip == null) {
            return;
        }

        // 获取音频播放的进度
        float progress = audioS.time / audioS.clip.length;

        // 输出播放进度
        //Debug.Log("当前歌曲播放进度:" + progress);
        this.playCurMusicProgress = progress;

    }
}

3.外部通过PlaySceneBgm.Instance 调用相关接口:


http://www.niftyadmin.cn/n/5326507.html

相关文章

postgresql16 物理复制与逻辑复制的实现和对比

本文面向想要练习 PostgreSQL 中数据库复制基础知识但可能无法访问远程服务器的初学者。我认为学习新技术时&#xff0c;在自己的机器上运行示例以巩固概念是至关重要的。对于副本来说&#xff0c;这可能很困难&#xff0c;因为许多可用的资源假设用户具有一定的 PostgreSQL 经…

uniapp开发微信小程序uni.chooseImage()部分机型不生效问题

bug场景&#xff1a; 点击不生效&#xff0c;无法调起手机的相册选择照片功能 解决方案 在小程序管理后台&#xff0c;更改用户隐私协议&#xff0c;增加选择照片功能 具体操作如下&#xff1a; 设置 基本设置 服务内容说明–>更新 增加信息类型 选中的照片或视频 等…

机器学习之协同过滤算法

概念 协同过滤是一类常用于推荐系统的机器学习算法,它基于用户行为历史或物品属性来推荐用户可能感兴趣的物品。协同过滤算法主要分为两种类型:基于用户的协同过滤和基于物品的协同过滤。 协同过滤的优点在于它不需要关于物品或用户的领域知识,而是通过挖掘用户行为数据中的…

[我的Rust库更新]get_local_info 0.2.3

今天收到西安城市开发者社区的文章收录通知&#xff0c;谢谢社区的肯定。 随即发布0.2.3版本&#xff0c;增加峰值算法。 get_local_info是一个获取linux本地信息的Rust三方库&#xff0c;其目标是降低获取本地linux系统信息的难度。支持银河麒麟10、UOS、鸿蒙等国产系统。 项…

Java 并发性和多线程3

七、线程安全及不可变性 当多个线程同时访问同一个资源&#xff0c;并且其中的一个或者多个线程对这个资源进行了写操作&#xff0c;才会产生竞态条件。多个线程同时读同一个资源不会产生竞态条件。 我们可以通过创建不可变的共享对象来保证对象在线程间共享时不会被修改&…

HarmonyOS 工程目录介绍

工程目录 AppScope&#xff1a;存放应用全局所需要的资源文件 base element&#xff1a;文件夹主要存放公共的字符串、布局文件等资源media&#xff1a;存放全局公共的多媒体资源文件app.json5&#xff1a;应用的全局的配置文件&#xff0c;用于存放应用公共的配置信息 {"…

php 函数声明与调用

在 PHP 中&#xff0c;函数声明和调用的语法如下&#xff1a; 函数声明的一般形式为&#xff1a; function functionName($param1, $param2, ...) {// 函数体return $result; // 可选 } 例如&#xff1a; function add($a, $b) {return $a $b; } 函数调用的一般形式为&am…

C# OpenCvSharp DNN 部署yolov3目标检测

目录 效果 yolov3.cfg 项目 代码 下载 C# OpenCvSharp DNN 部署yolov3目标检测 效果 yolov3.cfg [net] # Testing #batch1 #subdivisions1 # Training batch16 subdivisions1 width416 height416 channels3 momentum0.9 decay0.0005 angle0 saturation 1.5 exposure 1…