Skip to main content
 首页 » 资源教程 » Unity3D教程

Unity3D热更新LuaFramework入门实战(8)——声音管理器

2016年10月15日 17:53:348220

LuaFramework内置的管理器包括GameManager(处理热更新)、luaManager(lua脚本管理器)、PanelManager(界面管理器)、NetworkManager(网络管理器)、ResourceManager(资源管理器)、TimerManager(时间管理器)、线程管理器(ThreadManager)和SoundManager(声音管理器)。其中GameManager、luaManager、PanelManager、NetworkManager、ResourceManager在前面的文章中已经有过介绍,这一篇讲讲讲播放声音相关的SoundManager。

by 罗培羽

1、使用方法

SoundManager估计是从其他地方拷过来的,并不能很好的与框架结合,这里我们先看看原来的SoundManager的使用方法,再介绍它的不足之处及改进方法。虽然SoundManager定义了好几个方法,但能直接在lua中使用的只有用于播放背景音乐的PlayBacksound。

编写播放声音的代码前,需要在GameManager上挂载AudioSource组件,以播放背景音乐。

Unity3D热更新LuaFramework入门实战(8)——声音管理器 Unity3D教程 第1张

把声音文件放到Resource目录下,由于SoundManager使用Resources.Load加载声音文件,声音文件必须放到这个目录下。如下图所示。

Unity3D热更新LuaFramework入门实战(8)——声音管理器 Unity3D教程 第2张

然后编写lua代码,调用soundMgr:PlayBacksound即可,它的第一个参数指明Resource目录下的文件名,第二个参数为true表示开始播放,false表示停止播放。

--主入口函数。从这里开始lua逻辑
function Main()					
	LuaHelper = LuaFramework.LuaHelper;
	soundMgr = LuaHelper.GetSoundManager();
	soundMgr:PlayBacksound("motor", true)
end

运行游戏,即可听到音效。关于Unity3D播放声音的内容,大家也可以参考《Unity3D网络游戏实战》哦!

2、代码解析

SoundManager的示意代码如下,实际上是使用Resources.Load来加载资源的,所以声音文件必须放在Resources目录下。

Unity3D热更新LuaFramework入门实战(8)——声音管理器 Unity3D教程 第3张

这种用法违背了热更新框架的设计,因为在Resources目录下的文件并不能热更。

3、改进的声音管理器

这一部分我们需要改进声音管理器,实现这么几个功能:

1)从本地“数据目录”读取打包后的声音文件,使它支持热更新;

2)添加播放/停止背景音乐的PlayBackSound/StopBackSound和播放音效的PlaySound方法;

3)使用缓存存储加载后的声音文件,以提高运行效率。

为了支持加载AudioClip的加载,在ResourceManager中添加LoadAudioClip方法,该方法将会加载资源包abName的资源assetName,加载完AudioClip资源后调用回调函数func,代码如下。

//载入音效资源
public void LoadAudioClip(string abName, 
                                  string assetName, Action<UObject[]> func) 
{
	LoadAsset<AudioClip>(abName, new string[] { assetName }, func);
}

修改SoundManager,使用Hashtable类型的sounds存储加载后的声音,包含PlayBackSound、StopBackSound和PlaySound三个API。代码如下所示。

先是整体kuan

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
 
namespace LuaFramework 
{
    public class SoundManager : Manager 
    {
	private AudioSource audio;
	private Hashtable sounds = new Hashtable();
	string backSoundKey = "";
 
	void Start() 
	{
		audio = GetComponent<AudioSource>();
		if (audio == null)
			gameObject.AddComponent<AudioSource> ();
	}
 
	//回调函数原型
	private delegate void GetBack(AudioClip clip, string key);
 
	//获取声音资源
	private void Get(string abName, string assetName, GetBack cb)
	{
		string key = abName + "." + assetName;
		if(sounds [key] == null) 
		{
			ResManager.LoadAudioClip(abName, assetName, (objs)=>
			{
				if(objs == null || objs[0] == null)
				{
					Debug.Log("PlayBackSound fail);
					cb(null,key);
					return;
				}
				else
				{
					sounds.Add(key, objs[0]);
					cb(objs[0] as AudioClip ,key);
					return;
				}
			});
		} 
		else 
		{
			cb(sounds [key] as AudioClip,key);
			return;
		}
	}
  }
}

PlayBackSound:

	//播放背景音乐
	public void PlayBackSound(string abName, string assetName)
	{
		backSoundKey = abName + "." + assetName;
		Get(abName, assetName,(clip, key)=>
		{
			if(clip == null)
				return;
			if(key != backSoundKey)
				return;
 
			audio.loop = true;
			audio.clip = clip;
			audio.Play();
		});
	}

StopBackSound:

	//停止背景音乐
	public void StopBackSound()
	{
		backSoundKey = "";
		audio.Stop ();
	}

 	//播放音效
	public void PlaySound(string abName, string assetName)
	{
		Get(abName, assetName,(clip, key)=>
		{
 
			if(clip == null)
				return;
			if(Camera.main == null)
				return;
		AudioSource.PlayClipAtPoint(clip, 
					Camera.main.transform.position); 
		});
	}

修改代码后,需要重新生成wrap文件(点击菜单栏的Lua→Clear wrap files和Lua→Generate All)。然后编写lua代码调试它吧!这里演示的是先播放背景音乐,3秒后停止播放,每隔0.3秒播放一次音效的功能。

--主入口函数。从这里开始lua逻辑
function Main()					
	LuaHelper = LuaFramework.LuaHelper;
	soundMgr = LuaHelper.GetSoundManager();
	soundMgr:PlayBackSound("sound", "motor")
	UpdateBeat:Add(Update, self)
end
 
 
local lastTime = 0
 
function Update()
	if Time.time > 3 then
		soundMgr:StopBackSound();
	end
	
	
	if Time.time - lastTime > 0.3 then
		soundMgr:PlaySound("sound", "shoot")
		lastTime = Time.time
	end
end

读者还可以使用类似 LoadAudioClip的方法加载其他资源,笔者也是刚刚接触LuaFramework不久,文章错误之处在所难免,请大家多加包涵。


最后是广告时间:

《16年的长度 记录中国独立游戏》从十多年前程序员写的小玩儿,到如今使用游戏引擎开发的炫酷产品,独立游戏作者的故事见证了我国游戏业的发展历程。来看看国产单机的造梦者们,在这十几年中做出怎么的作品,现在又过得如何。

16年的长度 记录中国独立游戏

《仙剑5前传之心愿》是笔者两年前发起的一款仙剑同人游戏,使用Unity3D制作,是市面上第一款能够完成的3D仙剑同人游戏。如今我们各自踏上游戏开发一途,似乎要做点什么以致敬国产经典之作,在追求商业成就的同时,勿忘初心。可以在仙剑5前传之心愿下载该游戏。《仙剑5前传之心愿》截图如下。

Unity3D热更新LuaFramework入门实战(8)——声音管理器 Unity3D教程 第4张

评论列表暂无评论
发表评论