Контролиране на броя на възпроизвежданите едновременни звукови ефекти

Страницата се актуализира :
Дата на създаване на страница :

Среда за проверка

Уиндоус
  • Прозорци 11
Редактор на единство
  • 2021.3.3f1
Пакет на входната система
  • 1.3.0

Предпоставки за този съвет

Следните настройки са направени предварително като предпоставка за описанието на този съвет.

За материала, включен в пробата

Звуковите ефекти са заимствани от следните сайтове.

За аудио файловете

Следните аудио файлови формати могат да се възпроизвеждат със стандартните функции на Unity: Моля, подгответе го предварително, защото ще бъде използван в тези съвети.

  • WAV (.wav)
  • ОгВорбис (.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 може да не е достатъчна, така че може да е добра идея да можете да зададете горна граница за всеки тип звук. Е, не знам дали има такава възможност за наслояване на звука, но ...