控制同时播放的音效数量
验证环境
- 窗户
-
- 视窗 11
- 统一编辑器
-
- 2021.3.3f1
- 输入系统包
-
- 1.3.0
此提示的先决条件
作为此提示描述的前提,已预先进行了以下设置。
关于样品中包含的材料
音效是从以下网站借来的。
关于音频文件
可以使用 Unity 的标准功能播放以下音频文件格式: 请提前准备,因为它将在这些提示中使用。
- 波浪 (.wav)
- 奥格沃比斯 (.ogg)
- MPEG 第 3 层 (.mp3)
有关更多信息,请参阅官方 Unity 文档。
关于多个同时播放音频的上限和音量
在前面的提示中, AudioClip
现在可以通过在 中准备 AudioSource.PlayOneShot
音频数据时播放多个语音来播放多个语音。
但是,可以玩的游戏数量没有限制,因此如果您在游戏过程中不限制它,可能会播放很多声音并且可能会播放很大的音量。
在这里,我想创建自己的程序并控制可以同时播放的音效数量。
创建示例
这一次,每次单击按钮时都会播放音效,因此请创建如图所示的 UI。 细节是适当和好的。
拖放要播放的音频文件并将其添加到项目中。
直到上次,标准功能 AudioSource
被添加到层次结构中,
这一次,我们将添加一个脚本,因为我们将放置自己的控件。
SoundPlayManager
将名称保留为 。
按如下方式创建脚本:
using System.Collections.Generic;
using UnityEngine;
<summary>音声再生管理クラスです。</summary>
public class SoundPlayManager : MonoBehaviour
{
<summary>1つの種類の音声の再生情報を保持するクラスです。</summary>
private class PlayInfo
{
<summary>再生している AudioSource の一覧です。</summary>
public AudioSource[] AudioSource { get; set; }
<summary>現在の再生インデックスです。</summary>
public int NowIndex { get; set; }
}
<summary>再生しようとしている音声データのキューです。</summary>
private HashSet<AudioClip> Queue = new HashSet<AudioClip>();
<summary>再生している音声を管理している一覧です。</summary>
private Dictionary<AudioClip, PlayInfo> Sources = new Dictionary<AudioClip, PlayInfo>();
<summary>
同一音声同時再生最大数。
</summary>
[SerializeField, Range(1, 32)] private int MaxSimultaneousPlayCount = 2;
protected void Update()
{
foreach (var item in Queue)
{
AudioSource source;
if (Sources.ContainsKey(item) == false)
{
// 一度も再生されていない Clip がある場合は PlayInfo を生成します
var info = new PlayInfo()
{
AudioSource = new AudioSource[MaxSimultaneousPlayCount],
};
for (int i = 0; i < MaxSimultaneousPlayCount; i++)
{
var s = gameObject.AddComponent<AudioSource>();
s.clip = item;
info.AudioSource[i] = s;
}
Sources.Add(item, info);
source = info.AudioSource[0];
}
else
{
// 再生に使用する AudioSource を順番に取得します
var info = Sources[item];
info.NowIndex = (info.NowIndex + 1) % MaxSimultaneousPlayCount;
source = info.AudioSource[info.NowIndex];
}
source.Play();
}
Queue.Clear();
}
<summary>
効果音を再生します。
</summary>
public void Play(AudioClip clip)
{
// 同一フレームで複数再生しないようにすでにキューに入っているか確認します
if (Queue.Contains(clip) == false)
{
Queue.Add(clip);
}
}
public void OnDestroy()
{
// 不要になった参照をすべて外します
foreach (var source in Sources)
{
source.Value.AudioSource = null;
}
Sources.Clear();
Queue.Clear();
}
}
由于脚本较长,省略了详细说明,但它具有以下功能。
AudioClip
您可以通过传递播放音频- 当相同类型的音频相互叠加播放时,如果尝试播放超过一定数量的声音,则旧的播放数据将停止(初始值最多播放 2 次)。
- 不允许在同一帧上重叠播放
这可以防止在背靠背播放相同音频时音量增加。 在功能方面,仅包含最低限度,因此如果需要,请添加它。
该脚本将附加到事件系统。
接下来,为按钮创建脚本。
按如下方式创建脚本:
using UnityEngine;
public class ButtonEvent : MonoBehaviour
{
<summary>再生する音声データ。</summary>
[SerializeField] private AudioClip AudioClip;
<summary>自作した音声再生管理クラス。</summary>
[SerializeField] private SoundPlayManager SoundPlayManager;
<summary>ボタンをクリックしたとき。</summary>
public void OnClick()
{
SoundPlayManager.Play(AudioClip);
}
}
播放过程由自制 SoundPlayManager
自己完成,因此在按钮事件中,只需传递音频数据并播放即可。
该脚本将附加到事件系统。 附加管理不是本提示的主要主题,因此它是合适的。
对于音频剪辑,设置要播放的音频文件。
将声音播放管理器 SoundPlayManager
设置为要附加到的对象。
由于我们正在附加到事件系统,因此我们将设置事件系统。
最后,分配给 OnClick
按钮单击事件。
完成后运行游戏。 默认情况下,最大同时播放次数设置为 2,因此请在播放两个声音时再次单击该按钮,并确保第一个声音消失。
这次创建的程序对每种声音的播放次数有上限,因此即使您交织其他音效,听起来也很自然。 但是,根据声音的类型,2 的上限可能还不够,因此能够为每种声音类型设置上限可能是个好主意。 好吧,我不知道是否有这样的机会来分层声音,但是......