14_音乐播放服务_字典缓存避免重复加载

首先在游戏根入口下创建空节点

F2重命名为BGAudio 作为播放 背景音乐的对象

在BGAudio对象上挂载组件 AudioSource

关掉PlayOnAwake

因为我们需要通过代码来控制音效

音量大小设置为0.5

Ctrl + d 再复制一份背景播放对象BGAudio

重命名为UIAudio 作为UI窗口操作的播放对象

创建脚本 AudioSvc.cs

编写脚本 音乐播放服务 很多地方需要用到 所以设置成单例 增加一个初始化方法

cs 复制代码
using UnityEngine;
//功能 : 音乐播放服务
public class AudioSvc : MonoBehaviour{
    public static AudioSvc Instance;
    public void InitSvc(){
        Instance = this;
        Debug.Log("Init AudioSvc...");
    }
}

在游戏根入口GameRoot.cs添加音乐播放服务的初始化函数

因为GameRoot.cs用到GetComponent<>()组件 所以需要将 AudioSvc.cs要挂载至GameRoot对象身上

继续编写音乐播放服务脚本AudioSvc.cs

对场景对象进行关联

拿到这两个组件之后我们就可以利用这两个组件来播放音效

这里我们需要资源服务ResSvc.cs的函数 所以在资源服务ResSvc.cs中添加函数

现在我们在项目中添加一个音乐资源

先在Resources文件夹下创建一个空文件命名为ResAudio

导入资源文件

继续编写代码 - 资源加载服务层ResSvc.cs

cs 复制代码
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement; //异步加载 命名空间
//功能 : 资源加载服务
public class ResSvc : MonoBehaviour{
    #region 单例模式
    public static ResSvc Instance = null;
    #endregion
    public void InitSvc(){
        #region 单例模式
        Instance = this;
        #endregion
        Debug.Log("Init ResSvc...");
    }
    #region 【委托】更新回调 进度值
    Action prgCB = null;
    #endregion
    //自定义异步加载
    public void AsyncLoadScene(string sceneName,Action loaded) {
        #region 窗口基类的好处
        GameRoot.Instance.loadingWnd.SetWndState();
        #endregion
        //拿到异步操作
        AsyncOperation sceneAsync = SceneManager.LoadSceneAsync(sceneName);
        #region 【委托】更新回调 进度值
        //Lamd表达式
        prgCB = () =>{
            //当前加载进度
            float val = sceneAsync.progress;
            GameRoot.Instance.loadingWnd.SetProgress(val);
            if (val == 1){
                #region Loaded回调判断
                if (loaded != null)
                    loaded();
                #endregion
                #region 单例调用打开登录窗口
                //LoginSys.Instance.OpenLoginWnd();
                #endregion
                //当进度满后 进度值 置空
                prgCB = null;
                sceneAsync = null;
                GameRoot.Instance.loadingWnd.gameObject.SetActive(false);
            }
        };
        #endregion
    }
    #region 【委托】更新回调 进度值
    void Update(){
        if(prgCB != null)
            prgCB();
    }
    #endregion
    #region 音乐播放资源_字典
    Dictionary<string,AudioClip> adDic = new Dictionary<string,AudioClip>();
    public AudioClip LoadAudio(string path, bool cache = false) {
        AudioClip au = null;
        //检查路径是否存在 需要对资源进行加载
        //out的作用是 如果路径已经存在这个资源 那么out直接就返回了
        if (!adDic.TryGetValue(path, out au)) {
            au = Resources.Load<AudioClip>(path);
            //检查是否需要缓存 避免重复加载
            if (cache) {
                adDic.Add(path, au);
            }
        }
        return au;
    }
    #endregion
}

音乐播放服务层AudioSvc.cs

cs 复制代码
using UnityEngine;
//功能 : 音乐播放服务
public class AudioSvc : MonoBehaviour{
    public static AudioSvc Instance;
    //背景音乐播放对象
    public AudioSource bgAudio;
    //窗口音乐播放对象
    public AudioSource uiAudio;
    public void InitSvc(){
        Instance = this;
        Debug.Log("Init AudioSvc...");
    }
    //播放背景音乐
    public void PlayBGMusic(string name, bool isLoop) {
        //路径 与 缓存
        AudioClip audio = ResSvc.Instance.LoadAudio("ResAudio/" + name,true);
        //检查背景音乐没有了 或 背景音乐名字不是目标名字 (代表切换音乐)
        if (bgAudio.clip == null || bgAudio.clip.name != audio.name) {
            bgAudio.clip = audio;
            bgAudio.loop = isLoop;
            bgAudio.Play();
        }
    }
    //播放窗口操作音效
    public void PlayUIAudio(string name) {
        //路径 与 缓存
        AudioClip audio = ResSvc.Instance.LoadAudio("ResAudio/" + name, true);
        uiAudio.clip = audio;
        uiAudio.Play();
    }
}

这样我们就可以在 业务系统中调用了

我们需要定义一个常量

添加常量

cs 复制代码
using UnityEngine;
//功能 : 登陆注册业务系统
public class LoginSys : MonoBehaviour{
    #region 单例模式
    public static LoginSys Instance = null;
    #endregion
    #region 引用登录窗口
    public LoginWnd loginWnd;
    #endregion
    public void InitSys() {
        #region 单例模式
        Instance = this;
        #endregion
        Debug.Log("Init LoginSys...");
    }
    //进入登录界面
    public void EnterLogin() {
        //TODO
        //异步加载登录界面
        //并显示加载进度
        #region 调用ResSvc单例类
        ResSvc.Instance.AsyncLoadScene(Constans.SceneLogin,() => {
            #region 窗口基类的好处
            loginWnd.SetWndState();
            #endregion
            #region 调用音乐播放服务
            AudioSvc.Instance.PlayBGMusic(Constans.BGLogin,true);
            #endregion
        });
        #endregion
    }
}

运行项目

这样在运行时就可以听见背景音乐了

End.

相关推荐
__water1 小时前
15_业务系统基类
c#·unity6000·业务系统基类
AitTech4 小时前
C#编程:List.ForEach与foreach循环的深度对比
开发语言·c#·list
军训猫猫头5 小时前
56.命令绑定 C#例子 WPF例子
开发语言·c#·wpf
小唐C++7 小时前
C++小病毒-1.0勒索
开发语言·c++·vscode·python·算法·c#·编辑器
菜鸟记录7 小时前
C#AWS signatureV4对接Amazon接口
c#·aws·amazon·aksk
课堂随想8 小时前
`std::make_shared` 无法直接用于单例模式,因为它需要访问构造函数,而构造函数通常是私有的
c++·单例模式
w(゚Д゚)w吓洗宝宝了8 小时前
单例模式 - 单例模式的实现与应用
开发语言·javascript·单例模式
上位机付工8 小时前
浅谈单例模式
开发语言·c#
步、步、为营9 小时前
从0到1:.NET Core微服务的Docker容器奇幻冒险
微服务·c#·asp.net·.net·.netcore