Mengawal bilangan kesan bunyi serentak yang dimainkan
Persekitaran pengesahan
- Windows
-
- Windows 11
- Penyunting Perpaduan
-
- 2021.3.3F1
- Pakej Sistem Input
-
- 1.3.0
Prasyarat untuk petua ini
Tetapan berikut telah dibuat terlebih dahulu sebagai premis untuk penerangan petua ini.
Mengenai bahan yang disertakan dengan sampel
Kesan bunyi dipinjam dari laman web berikut.
Perihal fail audio
Format fail audio berikut boleh dimainkan dengan ciri standard Unity: Sila sediakannya terlebih dahulu kerana ia akan digunakan dalam petua ini.
- WAV (.wav)
- OggVorbis (.ogg)
- MPEG lapisan 3 (.mp3)
Untuk maklumat lanjut, lihat dokumentasi Unity rasmi.
Perihal had atas dan kelantangan main balik audio berbilang serentak
Dalam petua sebelumnya, AudioClip
kini mungkin untuk memainkan berbilang suara dengan memainkannya semasa menyediakan AudioSource.PlayOneShot
data audio dalam .
Walau bagaimanapun, tiada had kepada bilangan permainan yang boleh dimainkan, jadi jika anda tidak mengehadkannya semasa permainan, banyak bunyi boleh dimainkan dan kelantangan yang kuat boleh dimainkan.
Di sini saya ingin membuat program saya sendiri dan mengawal bilangan kesan bunyi yang boleh dimainkan pada masa yang sama.
Buat sampel
Kali ini, kesan bunyi akan dimainkan setiap kali anda mengklik butang, jadi buat UI seperti yang ditunjukkan dalam gambar. Butirannya sesuai dan baik.
Lepaskan dan tambah fail audio yang ingin anda mainkan ke dalam projek anda.
Sehingga kali terakhir, fungsi AudioSource
standard telah ditambahkan pada hierarki,
Kali ini, kami akan menambah skrip kerana kami akan meletakkan kawalan kami sendiri.
SoundPlayManager
Tinggalkan nama sebagai .
Buat skrip seperti berikut:
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();
}
}
Oleh kerana skripnya panjang, penjelasan terperinci ditinggalkan, tetapi ia mempunyai fungsi berikut.
AudioClip
Anda boleh memainkan audio dengan lulus- Apabila jenis audio yang sama dimainkan di bahagian atas satu sama lain, jika anda cuba memainkan lebih daripada bilangan suara tertentu, data main balik lama berhenti (nilai awal adalah sehingga 2 main balik).
- Main balik bertindih pada bingkai yang sama tidak dibenarkan
Ini menghalang kelantangan daripada meningkat apabila audio yang sama dimainkan secara back-to-back. Dari segi fungsi, hanya minimum yang disertakan, jadi sila tambahkannya jika anda memerlukannya.
Skrip dilampirkan pada EventSystem.
Seterusnya, buat skrip untuk butang.
Buat skrip seperti berikut:
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);
}
}
Proses main balik dilakukan oleh SoundPlayManager
diri sendiri, jadi dalam acara butang, hanya lulus data audio dan mainkannya.
Skrip dilampirkan pada EventSystem. Lampirkan pengurusan bukan topik utama Petua ini, jadi sesuai.
Untuk klip audio, tetapkan fail audio untuk dimainkan.
Setkan Pengurus Main Bunyi kepada objek yang SoundPlayManager
anda lampirkan.
Oleh kerana kami melampirkan kepada EventSystem, kami akan menetapkan EventSystem.
Akhirnya, berikan kepada butang klik OnClick
peristiwa.
Jalankan permainan apabila anda selesai. Secara lalai, bilangan maksimum permainan serentak ditetapkan kepada 2, jadi sila klik butang sekali lagi semasa dua bunyi dimainkan dan pastikan bunyi pertama hilang.
Program yang dibuat kali ini mempunyai had atas bilangan masa main balik untuk setiap jenis bunyi, jadi ia kedengaran semula jadi walaupun anda mengaitkan kesan bunyi lain. Walau bagaimanapun, bergantung pada jenis bunyi, had atas 2 mungkin tidak mencukupi, jadi mungkin idea yang baik untuk dapat menetapkan had atas untuk setiap jenis bunyi. Baiklah, saya tidak tahu sama ada terdapat peluang untuk melapisi bunyi, tetapi ...