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.