Unity类银河战士恶魔城学习总结(P157 Audio Time Limter ---P158 Area Sound范围音效)
【Unity教程】从0编程制作类银河恶魔城游戏_哔哩哔哩_bilibili
教程源地址:https://www.udemy.com/course/2d-rpg-alexdev/
本章节实现了创造一个有特殊音效的区域,这样就可以创造一个自带BGM的男人
绿色方框就是特殊音效区域
给特殊音效区域加上物理碰撞器,作为碰撞触发
AudioManager.cs
添加部分!!!
用于停止音效(SFX)并逐渐减小音量的逻辑。
1. StopSFXWithTime(int _index)
:
- 功能:接收一个整数索引
_index
,用于停止对应音效的播放,并且逐渐减小音量,直到音量降到 0.1 以下。 - 实现:此方法调用
StartCoroutine(DecreaseVolume(sfx[_index]))
,启动一个协程来执行音量逐渐减小的逻辑。sfx
应该是一个AudioSource
数组,存储了多个音效资源。
2. DecreaseVolume(AudioSource _audio)
(协程):
- 功能:这是一个逐渐减小音效音量的协程。
- 参数:
_audio
是一个AudioSource
对象,表示需要减小音量的音效。 - 实现:
float defaultVolume = _audio.volume;
:保存音效的初始音量,以便在音量减小完成后恢复音量。while(_audio.volume > .1f)
:当音效的音量大于 0.1 时,不断执行音量减少的操作。音量降到 0.1 以下时,停止音效并恢复音量。_audio.volume -= _audio.volume * .2f;
:每次循环中,音量减少 20%(_audio.volume * .2f
)。这是通过将当前音量减去其 20% 实现的,因此音量逐渐减小。yield return new WaitForSeconds(.65f);
:每次减小音量后,等待 0.65 秒。这个时间间隔控制了音量逐渐减小的速度。if(_audio.volume <= .1f)
:当音量降到 0.1 或以下时,停止音效播放并恢复音量:_audio.Stop();
:停止音效播放。_audio.volume = defaultVolume;
:恢复音效的原始音量。break;
:结束while
循环。
修改部分!!!
public void StopSFXWithTime(int _index)=> StartCoroutine(DecreaseVolume(sfx[_index]));//停止对应音效的播放,并且逐渐减小音量
private IEnumerator DecreaseVolume(AudioSource _audio)//减小音量
{
float defaultVolume = _audio.volume;//保存默认音量
while (_audio.volume > .1f)
{
_audio.volume -= _audio.volume * .2f;//每次减小20%音量
yield return new WaitForSeconds(.65f);
if(_audio.volume <=.1f)
{
_audio.Stop();
_audio.volume = defaultVolume;//音量恢复
break;
}
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class AudioManager : MonoBehaviour
{
public static AudioManager instance;
[SerializeField] private float sfxMinimumDistance;//音效最小距离
[SerializeField] private AudioSource[] sfx;//音效
[SerializeField] private AudioSource[] bgm;//背景音乐
public bool playBgm;
private int bgmIndex;
private bool canPlaySFX;
private void Awake()
{
if(instance != null)
Destroy(instance.gameObject);
else
instance = this;
Invoke("AllowSFX", 1f);//P157,加入一个协程防止进入音频听到点击的声音
}
private void Update()
{
if (!playBgm)
StopAllBGM();
else
{
if(!bgm[bgmIndex].isPlaying)//如果背景音乐没有播放
PlayBGM(bgmIndex);
}
}
public void PlaySFX(int _sfxIndex,Transform _source)//播放音效
{
//if(sfx[_sfxIndex].isPlaying)//如果音效正在播放
// return;
if (canPlaySFX == false)
return;
if(_source!=null && Vector2.Distance(PlayerManager.instance.player.transform.position, _source.position) > sfxMinimumDistance)//距离过远不播放
return;
if (_sfxIndex < sfx.Length)
{
sfx[_sfxIndex].pitch = Random.Range(.85f, 1.15f);//设置音效的音调
sfx[_sfxIndex].Play();
}
}
public void StopSFX(int _index) => sfx[_index].Stop();//停止音效
public void StopSFXWithTime(int _index)=> StartCoroutine(DecreaseVolume(sfx[_index]));//停止对应音效的播放,并且逐渐减小音量
private IEnumerator DecreaseVolume(AudioSource _audio)//减小音量
{
float defaultVolume = _audio.volume;//保存默认音量
while (_audio.volume > .1f)
{
_audio.volume -= _audio.volume * .2f;//每次减小20%音量
yield return new WaitForSeconds(.65f);
if(_audio.volume <=.1f)
{
_audio.Stop();
_audio.volume = defaultVolume;//音量恢复
break;
}
}
}
public void PlayRandomBGM()//播放随机背景音乐
{
bgmIndex = Random.Range(0, bgm.Length);
PlayBGM(bgmIndex);
}
public void PlayBGM(int _bgmIndex)//播放背景音乐
{
bgmIndex = _bgmIndex;
StopAllBGM();
bgm[bgmIndex].Play();
}
public void StopAllBGM()
{
for (int i = 0; i < bgm.Length; i++)
{
bgm[i].Stop();
}
}
private void AllowSFX() =>canPlaySFX = true;
}
AreaSound.cs
用于在玩家进入和离开特定触发区域时播放和停止音效。主要功能是通过触发器 (Collider) 来控制音效的播放
1. 成员变量:
areaSoundIndex
:这是一个整数变量,表示在AudioManager
中用来播放或停止音效的索引。它用于标识不同的音效资源。
2. nTriggerEnter2D(Collider2D collision)
:
- 功能:当一个物体进入触发区域时调用该方法。
- 实现:
if(collision.GetComponent<Player>() != null)
:判断触发器接触的物体是否是Player
对象。如果接触的物体是玩家,则执行以下操作。AudioManager.instance.PlaySFX(areaSoundIndex, null)
:通过AudioManager
播放音效,使用areaSoundIndex
作为音效的索引,触发播放指定的音效。
3. OnTriggerExit2D(Collider2D collision)
:
- 功能:当一个物体离开触发区域时调用该方法。
- 实现:
if (collision.GetComponent<Player>() != null)
:再次判断触发器接触的物体是否是玩家。如果是玩家,执行以下操作。AudioManager.instance.StopSFXWithTime(areaSoundIndex)
:通过AudioManager
停止播放指定的音效。StopSFXWithTime
方法会逐渐减小音量并在音量降到 0.1 以下时停止音效。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//2024.12.2 秋风扫落叶
public class AreaSound : MonoBehaviour
{
[SerializeField] private int areaSoundIndex;//区域音效索引
private void nTriggerEnter2D(Collider2D collision)
{
if(collision.GetComponent<Player>() != null)
AudioManager.instance.PlaySFX(areaSoundIndex,null);
}
private void OnTriggerExit2D(Collider2D collision)
{
if (collision.GetComponent<Player>() != null)
AudioManager.instance.StopSFXWithTime(areaSoundIndex);
}
}