Керування кількістю одночасних звукових ефектів

Сторінка оновлюється :
Дата створення сторінки :

Середовище перевірки

Вікна
  • вікна 11
Редактор єдності
  • 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 може бути недостатньо, тому може бути гарною ідеєю встановити верхню межу для кожного типу звуку. Ну, не знаю, чи є така можливість нашарувати звук, але ...