Контролируйте количество одновременно воспроизводимых звуковых эффектов

Страница обновлена :
Дата создания страницы :

Среда верификации

Виндоус
  • Windows 11
Редактор Unity
  • 2021.3.3f1
Входной системный пакет
  • 1.3.0

Предпосылки для этого совета

Следующие настройки были сделаны заранее в качестве предпосылки для описания этого совета.

О материале, входящем в состав образца

Звуковые эффекты заимствованы со следующих сайтов.

Об аудиофайлах

Следующие форматы аудиофайлов могут воспроизводиться с помощью стандартных функций Unity: Пожалуйста, подготовьте его заранее, потому что он будет использоваться в этих советах.

  • WAV (.wav)
  • OggVorbis (.ogg)
  • MPEG уровень 3 (.mp3)

Дополнительные сведения см. в официальной документации по Unity.

О верхнем пределе и громкости одновременного воспроизведения звука

В предыдущих советах теперь можно воспроизводить несколько голосов, AudioClip воспроизводя их во время подготовки AudioSource.PlayOneShot аудиоданных в формате . Тем не менее, количество игр, в которые можно играть, не ограничено, поэтому, если вы не ограничите его во время игры, может воспроизводиться много звука и громкая громкость.

Здесь я хотел бы создать свою собственную программу и контролировать количество звуковых эффектов, которые могут воспроизводиться одновременно.

Создание образца

На этот раз звуковой эффект будет воспроизводиться каждый раз, когда вы нажимаете кнопку, поэтому создайте пользовательский интерфейс, как показано на рисунке. Детали уместны и хороши.

Перетащите и добавьте аудиофайл, который вы хотите воспроизвести, в свой проект.

До последнего раза в иерархию была добавлена стандартная функция AudioSource На этот раз мы добавим сценарий, потому что мы поставим свой собственный контроль. SoundPlayManager Оставьте имя как .

Создайте сценарий следующим образом:

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

Поскольку скрипт длинный, подробное объяснение опущено, но он имеет следующие функции.

  • AudioClip Вы можете воспроизводить звук, проходя мимо
  • При воспроизведении одного и того же типа звука друг на друга, если вы пытаетесь воспроизвести более определенного количества голосов, старые данные воспроизведения останавливаются (начальное значение — до 2 воспроизведений).
  • Перекрывающееся воспроизведение на одном кадре не допускается

Это предотвращает увеличение громкости при воспроизведении одного и того же звука подряд. Что касается функциональности, то включен только минимум, поэтому, пожалуйста, добавьте его, если вам это нужно.

Сценарий прикрепляется к EventSystem.

Далее создайте скрипт для кнопки.

Создайте сценарий следующим образом:

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

Процесс воспроизведения выполняется самим собой SoundPlayManager , поэтому в событии кнопки просто передайте аудиоданные и воспроизведите их.

Сценарий прикрепляется к EventSystem. Прикрепить менеджмент не является основной темой данного Совета, поэтому он уместен.

Для аудиоклипа установите аудиофайл для воспроизведения. Установите диспетчер воспроизведения звука на объект, SoundPlayManager к которому выполняется присоединение. Поскольку мы присоединяемся к EventSystem, мы установим EventSystem.

Наконец, назначьте кнопке событие клика OnClick .

Запустите игру, когда закончите. По умолчанию максимальное количество одновременных воспроизведений установлено на 2, поэтому, пожалуйста, нажмите кнопку еще раз во время воспроизведения двух звуков и убедитесь, что первый звук исчез.

Программа, созданная на этот раз, имеет верхний предел времени воспроизведения для каждого типа звука, поэтому она звучит естественно, даже если вы переплетаете другие звуковые эффекты. Однако, в зависимости от типа звука, верхнего предела 2 может быть недостаточно, поэтому может быть хорошей идеей иметь возможность установить верхний предел для каждого типа звука. Ну, не знаю, есть ли такая возможность наслоить звук, но...