第十天
前言
有两种不同的音频将会在以下教程中用到
无固定音源的声音(Non-diegetic sound),如背景音乐等等。
有来源的音乐(Diegetic sound),如枪声,声音来源于枪膛。
接下来我们开始为我们的游戏添加无固定音源的声音。
Unity音频入门
工作方式
在开始添加音频之前,我们快速了解一下音频在Unity种是如何工作的,主要有以下三部分
音频片段(Audio Clips)
诸如MP3之类的资源,其中包含特定声音的所有数据。
音频源(Audio Sources)
即游戏中充当声音来源的组件。大多数在游戏中的声音都应该有一个音频源组件,这样声音就有了一个具体位置。
音频监听器(The Audio Listener)
这是一个单独的组件用于充当玩家的虚拟耳朵,其工作方式类似于相机组件。默认情况下啊该组件在Main Camera上。
这些不同的部分通常这样工作:音频源播放音频片段,如果音频监听器与音频源足够接近,音频就能够被听见。
特定音源的空间混合(spatial blend)
能使特定的声音来自游戏中一个特定的点,或使声音大小与音源和监听器之间的距离无关,也就是无固定音源的声音。
无固定音源的声音没有原点,因此将它的空间混合设为2D。当音频的spatial blend被设为纯2D后,音频源和监听器之间的距离不会影响音量;如果设为纯3D,音量将随间隔距离变化。如果所设值在这之间两种效果的强度会随所设的值变化。
添加Non-diegetic sound
我们将添加三个Non-diegetic sound
第一:一个环境轨道循环播放制造一个大体的鬼屋气氛
第二:一个特效音乐当JohnLemon被抓住的后播放
第三:一个特效音乐当JohnLemon逃脱后播放
Setp 1 background music
创建一个空对象命名为Ambient,设置position为(0,0,0),为其添加Audio Source组件。
可以看到Spatial Blend已经是2D了所以不需要调整, Play On Awake被允许意味着该音频会在场景加载后第一时间开始播放。
另外该需要允许循环播放,所以勾选上Loop,测试后发现音量有点大,所以再将Volume设置为0.5后保存。
Step 2
用上一节使用的CTRL+D复制两个Ambient对象,并分别更名为Escape和Caught,如下图
将他们Audio Source属性中的Play On Awake和Loop都取消我们只希望这两个声音在特定的时候再响起,同样的方法为这两个对象添加AudioClip
建一个空对象Audio,将所有的音频对象都拖入其中,作为一个分类,保存。
Step 3 修改GameEnding脚本
已知结束判断是由GameEnding脚本控制的,我们需要对不同的结局播放相应的声音所以,将脚本作如下修改。
思路:创建两个AudioSource公共类对象用于关联我们的两个音频对象,在合适的时候调用他们的公共方法play来播放音频
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class GameEnding1 : MonoBehaviour
{
public AudioSource exitAudio;//关联音频
public AudioSource caughtAudio;//关联音频
public float fadeDuration = 1f;//渐变发生持续时间
public GameObject player;//用于添加John对象
bool m_IsPlayerAtExit;//是否逃脱游戏
bool m_IsPlayerCaught;//是否被抓住
bool m_HasAudioPlayed;//是否播放音频
float m_Timer;//记录持续时间
public CanvasGroup exitBackroundImageCanvasGroup;//用于关联CanvasGroup组件
public CanvasGroup caughtBackroundImageCanvasGroup;//用于关联CanvasGroup组件
public float displayImageDuration = 1f;
void OnTriggerEnter(Collider other)//触发器
{
if(other.gameObject == player)//如果触发者是John
{
m_IsPlayerAtExit = true;//游戏结束
}
}
void Update()//帧更新
{
if(m_IsPlayerAtExit)//如果触发了逃脱条件
{
EndLevel(exitBackroundImageCanvasGroup, false, exitAudio);//逐渐显示逃脱成功结束图片播放成功的音频,并退出游戏
}
else if(m_IsPlayerCaught)//如果被抓住
{
EndLevel(caughtBackroundImageCanvasGroup, true, caughtAudio);//组件显示逃脱失败图片播放失败的音频,并且重新开始游戏
}
}
void EndLevel (CanvasGroup imageCanvasGroup, bool doRestart, AudioSource audioSource)//根据第一个参数处理结束画面
{
if(!m_HasAudioPlayed)//如果没有音频在播放,防止重复
{
audioSource.Play();//根据传入的AudioSource播放音频
m_HasAudioPlayed = true;//正在播放音乐
}
m_Timer += Time.deltaTime;
if(doRestart)//是否重新开始游戏
{
caughtBackroundImageCanvasGroup.alpha = m_Timer / fadeDuration;//在一秒类组件显示失败图片
if (m_Timer > displayImageDuration + fadeDuration)//持续2秒
{
SceneManager.LoadScene(0);//重新加载你的第一个场景
}
}
else
{
exitBackroundImageCanvasGroup.alpha = m_Timer / fadeDuration;//在一秒内逐渐显示成功图片
if(m_Timer > displayImageDuration + fadeDuration)//持续2秒
{
Application.Quit();//退出
}
}
}
public void CaughPlayer ()
{
m_IsPlayerCaught = true;
}
}
Inspector中设置好接口后保存测试。
Step 4 添加脚步声
修改控制John行走的脚本
思路:创建一个AudioSource类型变量,start方法中使用GetComponent<类名>();方法初始化它,通过isWalking为Ture的时候,查看其数据成员isPlaying的值是否为True,若是则调用其方法Play();,否则调用Stop;方法。
首先创建一个
private AudioSource audioSource;
start()方法中添加
audioSource = GetComponent<AudioSource>();
FixedUpdate()方法中添加
if(state.isWalking)
{
if(!audioSource.isPlaying)
{
audioSource.Play();//会更改audioSouce.isPlaying为Ture
}
}
else
{
audioSource.Stop();//会更改audioSouce.isPlaying为false
}
保存
选中Main Cramera对象,移除Audio Listener组件,再选中JohnLemon对象,添加Audio Listener,最后将全部组件都加入prefab预设,点击Override
然后选择Apply All。
Step 5 添加幽灵的音效
进入幽灵的预设,Assets/Audio目录中找到SFXGhostMove Audio Clip文件,将其拖入Ghost对象,效果如下
其中禁用Play On Awake,启用Loop,Volume设置为0.4,Spatial Blend设为1全3D。打开3D Sound Settings选项,该设置控制着声音随距离变化的规则
将Max Distance设为10,你在10点距离以外的地方时就听不到幽灵发出的声音了。
Volume Rolloff 是设置声音的衰减方式,目前设置的是成对数衰减这在长距离的情况下效果很好。
由于最大距离只有10,所以将音量设为自定义衰减。
为了使声音听起来没有方向性将Spread设为180,完成效果如下
保存完成