Ovládání počtu současně přehrávaných zvukových efektů

Stránky aktualizovány :
Datum vytvoření stránky :

Ověřovací prostředí

Windows
  • Systém Windows 11
Editor jednoty
  • 2021.3.3f1
Vstupní systémový balíček
  • 1.3.0

Předpoklady pro tento tip

Následující nastavení byla provedena předem jako předpoklad pro popis tohoto tipu.

O materiálu obsaženém ve vzorku

Zvukové efekty jsou vypůjčeny z následujících stránek.

O zvukových souborech

Pomocí standardních funkcí Unity lze přehrávat následující formáty zvukových souborů: Připravte si ji předem, protože bude použita v těchto tipech.

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

Další informace najdete v oficiální dokumentaci k jednotě.

O horním limitu a hlasitosti vícenásobného současného přehrávání zvuku

V předchozích tipech AudioClip je nyní možné přehrávat více hlasů jejich přehráváním při přípravě AudioSource.PlayOneShot zvukových dat v . Počet her, které lze hrát, však není omezen, takže pokud jej během hry neomezíte, může se přehrávat velké množství zvuku a hlasitost.

Zde bych chtěl vytvořit svůj vlastní program a ovládat počet zvukových efektů, které lze přehrávat současně.

Vytvoření ukázky

Tentokrát se zvukový efekt přehraje pokaždé, když kliknete na tlačítko, takže vytvořte uživatelské rozhraní, jak je znázorněno na obrázku. Detaily jsou vhodné a dobré.

Přetáhněte a přidejte zvukový soubor, který chcete přehrát, do projektu.

Až do poslední doby byla do hierarchie přidána standardní funkce AudioSource Tentokrát přidáme skript, protože vložíme vlastní kontrolu. SoundPlayManager Název ponechte jako .

Vytvořte skript následujícím způsobem:

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

Vzhledem k tomu, že skript je dlouhý, podrobné vysvětlení je vynecháno, ale má následující funkce.

  • AudioClip Zvuk můžete přehrávat průchodem
  • Pokud se stejný typ zvuku přehrává nad sebou a pokusíte se přehrát více než určitý počet hlasů, stará data přehrávání se zastaví (počáteční hodnota je až 2 přehrávání).
  • Překrývající se přehrávání ve stejném snímku není povoleno

Tím se zabrání zvýšení hlasitosti při přehrávání stejného zvuku za sebou. Pokud jde o funkčnost, je zahrnuto pouze minimum, proto jej prosím přidejte, pokud jej potřebujete.

Skript je připojen k EventSystem.

Dále vytvořte skript pro tlačítko.

Vytvořte skript následujícím způsobem:

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 přehrávání provádí self-made SoundPlayManager sám, takže v události tlačítka stačí předat zvuková data a přehrát je.

Skript je připojen k EventSystem. Připojit správu není hlavním tématem tohoto Tipu, takže je to vhodné.

Pro zvukový klip nastavte zvukový soubor, který se má přehrát. Nastavte Správce přehrávání zvuku na SoundPlayManager objekt, ke kterému se připojujete. Vzhledem k tomu, že se připojujeme k EventSystem, nastavíme EventSystem.

Nakonec přiřaďte k tlačítku OnClick událost kliknutí.

Až budete hotovi, spusťte hru. Ve výchozím nastavení je maximální počet současných přehrání nastaven na 2, proto klikněte na tlačítko znovu, zatímco se přehrávají dva zvuky, a ujistěte se, že první zvuk zmizí.

Tentokrát vytvořený program má horní limit počtu přehrávacích časů pro každý typ zvuku, takže to zní přirozeně, i když prolínáte jiné zvukové efekty. V závislosti na typu zvuku však horní hranice 2 nemusí stačit, takže může být dobré mít možnost nastavit horní limit pro každý typ zvuku. No, nevím, jestli existuje taková příležitost vrstvit zvuk, ale ...