Kontrolowanie liczby jednoczesnych efektów dźwiękowych

Strona zaktualizowana :
Data utworzenia strony :

Środowisko weryfikacji

Windows
  • Okna 11
Edytor Unity
  • 2021.3.3f1
Pakiet systemu wejściowego
  • 1.3.0

Wymagania wstępne dotyczące tej porady

Poniższe ustawienia zostały wcześniej wprowadzone jako przesłanka do opisu tej wskazówki.

O materiale dołączonym do próbki

Efekty dźwiękowe są zapożyczone z następujących stron.

Informacje o plikach audio

Następujące formaty plików audio mogą być odtwarzane ze standardowymi funkcjami Unity: Proszę przygotować go z wyprzedzeniem, ponieważ zostanie wykorzystany w tych wskazówkach.

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

Aby uzyskać więcej informacji, zapoznaj się z oficjalną dokumentacją Unity.

Informacje o górnym limicie i głośności wielokrotnego jednoczesnego odtwarzania dźwięku

W poprzednich wskazówkach można teraz odtwarzać wiele głosów, AudioClip odtwarzając je podczas przygotowywania AudioSource.PlayOneShot danych audio w formacie . Nie ma jednak ograniczeń co do liczby gier, w które można grać, więc jeśli nie ograniczysz jej podczas gry, może być odtwarzanych dużo dźwięku i głośna głośność.

Tutaj chciałbym stworzyć własny program i kontrolować liczbę efektów dźwiękowych, które można odtwarzać w tym samym czasie.

Tworzenie przykładu

Tym razem efekt dźwiękowy będzie odtwarzany za każdym razem, gdy klikniesz przycisk, więc utwórz interfejs użytkownika, jak pokazano na rysunku. Szczegóły są odpowiednie i dobre.

Upuść i dodaj plik audio, który chcesz odtworzyć do projektu.

Do ostatniego razu standardowa funkcja AudioSource została dodana do hierarchii, Tym razem dodamy skrypt, ponieważ umieścimy własną kontrolę. SoundPlayManager Pozostaw nazwę jako .

Utwórz skrypt w następujący sposób:

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

Ponieważ skrypt jest długi, szczegółowe wyjaśnienie jest pomijane, ale ma następujące funkcje.

  • AudioClip Możesz odtwarzać dźwięk, przekazując
  • Gdy ten sam typ dźwięku jest odtwarzany jeden na drugim, jeśli próbujesz odtworzyć więcej niż określoną liczbę głosów, stare dane odtwarzania zostaną zatrzymane (wartość początkowa to maksymalnie 2 odtworzenia).
  • Odtwarzanie nakładające się w tej samej klatce jest niedozwolone

Zapobiega to zwiększaniu głośności podczas odtwarzania tego samego dźwięku jeden po drugim. Jeśli chodzi o funkcjonalność, uwzględniono tylko minimum, więc dodaj je, jeśli tego potrzebujesz.

Skrypt jest dołączony do EventSystem.

Następnie utwórz skrypt dla przycisku.

Utwórz skrypt w następujący sposób:

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 odtwarzania odbywa się samodzielnie SoundPlayManager , więc w przypadku przycisku po prostu przekaż dane audio i odtwórz.

Skrypt jest dołączony do EventSystem. Zarządzanie dołączaniem nie jest głównym tematem tych wskazówek, więc jest właściwe.

W przypadku klipu audio ustaw plik audio, który ma być odtwarzany. Ustaw Menedżera odtwarzania dźwięku na obiekt, SoundPlayManager do którego dołączasz. Ponieważ dołączamy do EventSystem, ustawimy EventSystem.

Na koniec przypisz do OnClick przycisku zdarzenie kliknięcia.

Uruchom grę, gdy skończysz. Domyślnie maksymalna liczba jednoczesnych odtworzeń jest ustawiona na 2, więc kliknij przycisk ponownie podczas odtwarzania dwóch dźwięków i upewnij się, że pierwszy dźwięk zniknął.

Program utworzony tym razem ma górny limit liczby czasów odtwarzania dla każdego typu dźwięku, więc brzmi naturalnie, nawet jeśli przeplatasz inne efekty dźwiękowe. Jednak w zależności od rodzaju dźwięku górna granica 2 może nie wystarczyć, więc dobrym pomysłem może być możliwość ustawienia górnego limitu dla każdego rodzaju dźwięku. Cóż, nie wiem, czy jest taka możliwość nawarstwienia dźwięku, ale...