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.

相关推荐
我是唐青枫2 小时前
C#.NET ReadOnlySequence 深入解析:多段内存遍历与零拷贝协议解析
网络·c#·.net
人工智能AI技术3 小时前
GTC炸场!C#集成NemoClaw企业级Agent实战教程
人工智能·c#
金币闪耀3 小时前
一种winform实时刷新日志内容的方法
c#
Vae_Mars4 小时前
华睿MVP:C#脚本的应用一
笔记·c#
筱璦5 小时前
期货软件开发「启动加载页 / 初始化窗口」
前端·c#·策略模式·期货
qq_390760395 小时前
简单的线程安全日志记录器
开发语言·数据库·c#
醉酒柴柴6 小时前
word创建样式以后应用于所有新文件
开发语言·学习·c#·word
JosieBook7 小时前
【WinForm】C# WinForms 跨线程更新 UI 避坑指南
开发语言·ui·c#
阿蒙Amon8 小时前
C#常用类库-详解Playwright
开发语言·c#
Real-Staok8 小时前
(集合)C / C++ 设计模式综合
单例模式·设计模式·代理模式