Mengontrol jumlah efek suara simultan yang diputar

Halaman Diperbarui :
Tanggal pembuatan halaman :

Lingkungan verifikasi

Windows
  • jendela 11
Editor Kesatuan
  • 2021.3.3f1
Paket Sistem Input
  • 1.3.0

Prasyarat untuk tip ini

Pengaturan berikut telah dibuat sebelumnya sebagai premis untuk deskripsi tip ini.

Tentang materi yang disertakan dengan sampel

Efek suara dipinjam dari situs-situs berikut.

Tentang file audio

Format file audio berikut dapat diputar dengan fitur standar Unity: Harap persiapkan terlebih dahulu karena akan digunakan dalam tips ini.

  • WAV (.wav)
  • OggVorbis (.ogg)
  • MPEG lapisan 3 (.mp3)

Untuk informasi selengkapnya, lihat dokumentasi resmi Unity.

Mengenai batas atas dan volume beberapa pemutaran audio simultan

Dalam tips sebelumnya, AudioClip sekarang dimungkinkan untuk memutar banyak suara dengan memutarnya sambil menyiapkan AudioSource.PlayOneShot data audio dalam format . Namun, tidak ada batasan jumlah permainan yang dapat dimainkan, jadi jika Anda tidak membatasinya selama pertandingan, banyak suara dapat dimainkan dan volume keras dapat dimainkan.

Di sini saya ingin membuat program saya sendiri dan mengontrol jumlah efek suara yang dapat dimainkan secara bersamaan.

Membuat sampel

Kali ini, efek suara akan diputar setiap kali Anda mengklik tombol, jadi buat UI seperti yang ditunjukkan pada gambar. Detailnya sesuai dan bagus.

Jatuhkan dan tambahkan file audio yang ingin Anda putar ke dalam proyek Anda.

Sampai terakhir kali, fungsi AudioSource standar ditambahkan ke hierarki, Kali ini, kita akan menambahkan skrip karena kita akan menempatkan kontrol kita sendiri. SoundPlayManager Biarkan nama sebagai .

Buat skrip sebagai 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();
  }
}

Karena skripnya panjang, penjelasan terperinci dihilangkan, tetapi memiliki fungsi-fungsi berikut.

  • AudioClip Anda dapat memutar audio dengan melewatkan
  • Ketika jenis audio yang sama diputar di atas satu sama lain, jika Anda mencoba memutar lebih dari jumlah suara tertentu, data pemutaran lama berhenti (nilai awal hingga 2 pemutaran).
  • Pemutaran yang tumpang tindih pada bingkai yang sama tidak diperbolehkan

Ini mencegah volume meningkat saat audio yang sama diputar berturut-turut. Dalam hal fungsionalitas, hanya minimum yang disertakan, jadi silakan tambahkan jika Anda membutuhkannya.

Skrip dilampirkan ke EventSystem.

Selanjutnya, buat skrip untuk tombol.

Buat skrip sebagai 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 pemutaran dilakukan oleh SoundPlayManager diri sendiri, jadi dalam acara tombol, cukup lewati data audio dan putar.

Skrip dilampirkan ke EventSystem. Manajemen lampirkan bukanlah topik utama Tips ini, jadi sudah tepat.

Untuk klip audio, atur file audio yang akan diputar. Atur Sound Play Manager ke objek yang SoundPlayManager Anda lampirkan. Karena kita melampirkan ke EventSystem, kita akan mengatur EventSystem.

Terakhir, tetapkan ke OnClick acara klik tombol.

Jalankan game setelah selesai. Secara default, jumlah maksimum pemutaran simultan diatur ke 2, jadi silakan klik tombol lagi saat dua suara diputar dan pastikan suara pertama menghilang.

Program yang dibuat kali ini memiliki batas atas jumlah waktu pemutaran untuk setiap jenis suara, sehingga terdengar alami bahkan jika Anda menjalin efek suara lainnya. Namun, tergantung pada jenis suaranya, batas atas 2 mungkin tidak cukup, jadi mungkin ide yang baik untuk dapat menetapkan batas atas untuk setiap jenis suara. Yah, saya tidak tahu apakah ada kesempatan untuk melapisi suara, tapi ...