控制同時播放的音效數量
驗證環境
- 窗戶
-
- 視窗 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 的上限可能還不夠,因此能夠為每種聲音類型設置上限可能是個好主意。 好吧,我不知道是否有這樣的機會來分層聲音,但是......