Nadzor števila predvajanih sočasnih zvočnih učinkov

Stran posodobljena :
Datum ustvarjanja strani :

Okolje za preverjanje

Windows
  • Windows 11
Urejevalnik Unity
  • 2021.3.3F1
Paket vhodnega sistema
  • 1.3.0

Predpogoji za ta nasvet

Naslednje nastavitve so bile vnaprej narejene kot premisa za opis tega nasveta.

O materialu, vključenem v vzorec

Zvočni učinki so izposojeni na naslednjih spletnih mestih.

O zvočnih datotekah

S standardnimi funkcijami Unity lahko predvajate naslednje oblike zapisa zvočnih datotek: Prosimo, pripravite ga vnaprej, ker bo uporabljen v teh nasvetih.

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

Za več informacij glejte uradno dokumentacijo Unity.

O zgornji omejitvi in glasnosti večkratnega hkratnega predvajanja zvoka

V prejšnjih nasvetih je zdaj mogoče predvajati več glasov tako, AudioClip da jih predvajate med pripravo AudioSource.PlayOneShot zvočnih podatkov v . Vendar pa število iger, ki jih je mogoče igrati, ni omejeno, zato, če ga med igro ne omejite, se lahko predvaja veliko zvoka in predvaja glasnost.

Tukaj bi rad ustvaril svoj program in nadzoroval število zvočnih učinkov, ki jih je mogoče predvajati hkrati.

Ustvarjanje vzorca

Tokrat se bo zvočni učinek predvajal vsakič, ko kliknete gumb, zato ustvarite uporabniški vmesnik, kot je prikazano na sliki. Podrobnosti so primerne in dobre.

Spustite in dodajte zvočno datoteko, ki jo želite predvajati, v projekt.

Do zadnjega časa je bila v hierarhijo dodana standardna funkcija AudioSource , Tokrat bomo dodali scenarij, ker bomo postavili svoj nadzor. SoundPlayManager Pustite ime kot .

Ustvarite skript na naslednji način:

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

Ker je scenarij dolg, je podrobna razlaga izpuščena, vendar ima naslednje funkcije.

  • AudioClip Zvok lahko predvajate mimo
  • Če se ista vrsta zvoka predvaja drug nad drugim in poskušate predvajati več kot določeno število glasov, se stari podatki o predvajanju ustavijo (začetna vrednost je največ 2 predvajanji).
  • Prekrivanje predvajanja v istem okvirju ni dovoljeno

To preprečuje povečanje glasnosti, ko se isti zvok predvaja vzporedno. Kar zadeva funkcionalnost, je vključen samo minimum, zato ga dodajte, če ga potrebujete.

Skript je priložen EventSystem.

Nato ustvarite skript za gumb.

Ustvarite skript na naslednji način:

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

Postopek predvajanja opravi sam SoundPlayManager , zato v primeru gumba samo posredujte zvočne podatke in jih predvajajte.

Skript je priložen EventSystem. Upravljanje prilaganja ni glavna tema teh nasvetov, zato je primerno.

Za zvočni posnetek nastavite zvočno datoteko, ki jo želite predvajati. Upravitelja predvajanja zvokov nastavite na predmet, SoundPlayManager na katerega se pripnete. Ker se navezujemo na EventSystem, bomo nastavili EventSystem.

Na koncu dodelite dogodku klika gumba OnClick .

Ko končate, zaženite igro. Privzeto je največje število sočasnih predvajanj nastavljeno na 2, zato med predvajanjem dveh zvokov znova kliknite gumb in se prepričajte, da prvi zvok izgine.

Program, ustvarjen tokrat, ima zgornjo omejitev števila časov predvajanja za vsako vrsto zvoka, zato zveni naravno, tudi če prepletate druge zvočne učinke. Vendar pa glede na vrsto zvoka zgornja meja 2 morda ne bo dovolj, zato je morda dobro, da lahko nastavite zgornjo mejo za vsako vrsto zvoka. No, ne vem, ali obstaja takšna priložnost, da se zvok položi, ampak ...