当前位置: 首页 > article >正文

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

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

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

在BGAudio对象上挂载组件 AudioSource

关掉PlayOnAwake

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

音量大小设置为0.5

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

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

创建脚本 AudioSvc.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

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

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();
    }
}

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

我们需要定义一个常量

添加常量

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.


http://www.kler.cn/a/514525.html

相关文章:

  • 大华大数据开发面试题及参考答案
  • 【Oracle数据库】创建表的同义词示例
  • windows git bash 使用zsh 并集成 oh my zsh
  • 微服务学习-Gateway 统一微服务入口
  • 第二十四课 Vue中子组件调用父组件数据
  • 小哆啦解题记:如何计算除自身以外数组的乘积
  • Dart语言的云计算
  • Linux 执行 fdisk -l 出现 GPT PMBR 大小不符 解决方法
  • 一部手机如何配置内网电脑同时访问内外网
  • 【面试题】Java 多线程编程基础知识
  • 分析一个深度学习项目并设计算法和用PyTorch实现的方法和步骤
  • 五、华为 RSTP
  • React 中hooks之useSyncExternalStore使用总结
  • NS3网络模拟器中如何利用Gnuplot工具像MATLAB一样绘制各类图形?
  • Vue - ref( ) 和 reactive( ) 响应式数据的使用
  • 22.日常算法
  • stm8s单片机(一) 工程塔建与第一个实验程序
  • 漏洞情报:为什么、要什么和怎么做
  • CrypTen——基于pytorch的隐私保护机器学习框架
  • Git进阶笔记系列(01)Git核心架构原理 | 常用命令实战集合
  • Julia语言的区块链
  • Java设计模式 三 工厂方法模式 (Factory Method Pattern)
  • HTML 基础入门:核心标签全解析
  • 深圳大学-计算机系统(3)-实验三取指和指令译码设计
  • simulink入门学习01
  • Redis、MongoDB 和 MySQL评估