Ovládanie počtu simultánnych prehrávaných zvukových efektov

Stránka aktualizovaná :
Dátum vytvorenia strany :

Prostredie overovania

Windows
  • Windows 11
Editor jednoty
  • 2021.3.3f1
Vstupný systémový balík
  • 1.3.0

Predpoklady pre tento tip

Nasledujúce nastavenia boli vykonané vopred ako predpoklad pre popis tohto tipu.

O materiáli zahrnutom do vzorky

Zvukové efekty sú požičané z nasledujúcich stránok.

Informácie o zvukových súboroch

Nasledujúce formáty zvukových súborov je možné prehrávať so štandardnými funkciami Unity: Pripravte si ho vopred, pretože bude použitý v týchto tipoch.

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

Viac informácií nájdete v oficiálnej dokumentácii Unity.

Horný limit a hlasitosť viacerých simultánnych prehrávaní zvuku

V predchádzajúcich tipoch AudioClip je teraz možné prehrávať viac hlasov ich prehrávaním pri príprave AudioSource.PlayOneShot zvukových údajov v . Počet hier, ktoré je možné hrať, však nie je obmedzený, takže ak ho počas hry neobmedzíte, môže sa hrať veľa zvuku a môže sa hrať hlasitá hlasitosť.

Tu by som chcel vytvoriť vlastný program a ovládať počet zvukových efektov, ktoré je možné súčasne prehrávať.

Vytvorenie ukážky

Tentokrát sa zvukový efekt prehrá zakaždým, keď kliknete na tlačidlo, takže vytvorte používateľské rozhranie, ako je znázornené na obrázku. Podrobnosti sú vhodné a dobré.

Presuňte a pridajte zvukový súbor, ktorý chcete prehrať, do projektu.

Až do poslednej chvíle bola do hierarchie pridaná štandardná funkcia AudioSource z, Tentokrát pridáme skript, pretože si dáme vlastnú kontrolu. SoundPlayManager Názov ponechajte ako .

Vytvorte skript nasledovne:

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

Keďže skript je dlhý, podrobné vysvetlenie je vynechané, ale má nasledujúce funkcie.

  • AudioClip Zvuk môžete prehrávať prechodom
  • Ak sa pri prehrávaní rovnakého typu zvuku prehráva jeden nad druhým, ak sa pokúsite prehrať viac ako určitý počet hlasov, staré údaje prehrávania sa zastavia (počiatočná hodnota je až 2 prehrávania).
  • Prekrývanie prehrávania na rovnakej snímke nie je povolené

Tým sa zabráni zvýšeniu hlasitosti pri prehrávaní rovnakého zvuku chrbtom k sebe. Pokiaľ ide o funkčnosť, je zahrnuté iba minimum, preto ho v prípade potreby pridajte.

Skript je pripojený k EventSystem.

Potom vytvorte skript pre tlačidlo.

Vytvorte skript nasledovne:

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);
  }
}

Proces prehrávania vykonáva sám SoundPlayManager , takže v tlačidlovej udalosti stačí odovzdať zvukové údaje a prehrať ich.

Skript je pripojený k EventSystem. Správa pripojení nie je hlavnou témou týchto tipov, preto je vhodná.

V prípade zvukového klipu nastavte zvukový súbor, ktorý sa má prehrať. Nastavte Správcu prehrávania zvuku na objekt, SoundPlayManager ku ktorému pripájate. Keďže sa pripájame k EventSystem, nastavíme EventSystem.

Nakoniec priraďte k tlačidlu OnClick udalosť kliknutia.

Po dokončení spustite hru. V predvolenom nastavení je maximálny počet súčasných prehratí nastavený na 2, preto kliknite na tlačidlo znova, kým sa prehrávajú dva zvuky, a uistite sa, že prvý zvuk zmizne.

Program vytvorený tentoraz má hornú hranicu počtu časov prehrávania pre každý typ zvuku, takže znie prirodzene, aj keď prepletáte iné zvukové efekty. V závislosti od typu zvuku však horná hranica 2 nemusí stačiť, takže môže byť dobré mať možnosť nastaviť hornú hranicu pre každý typ zvuku. No, neviem, či existuje taká príležitosť vrstviť zvuk, ale ...