Valdykite vienu metu grojamų garso efektų skaičių

Puslapis atnaujintas :
Puslapio sukūrimo data :

Tikrinimo aplinka

Windows
  • Langai 11
"Unity" redaktorius
  • 2021.3.3F1
Įvesties sistemos paketas
  • 1.3.0

Būtinos šio patarimo sąlygos

Šie nustatymai buvo atlikti iš anksto kaip šio patarimo aprašymo prielaida.

Apie medžiagą, įtrauktą į pavyzdį

Garso efektai yra pasiskolinti iš šių svetainių.

Apie garso failus

Naudojant standartines "Unity" funkcijas galima leisti šiuos garso failų formatus: Paruoškite jį iš anksto, nes jis bus naudojamas šiuose patarimuose.

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

Daugiau informacijos rasite oficialioje "Unity" dokumentacijoje.

Apie kelių garso įrašų atkūrimo vienu metu viršutinę ribą ir garsumą

Ankstesniuose patarimuose dabar galima leisti kelis balsus AudioClip juos grojant ruošiant AudioSource.PlayOneShot garso duomenis . Tačiau žaidimų, kuriuos galima žaisti, skaičius neribojamas, todėl, jei žaidimo metu jo neapribosite, gali būti žaidžiama daug garso ir gali būti žaidžiamas garsas.

Čia norėčiau sukurti savo programą ir valdyti garso efektų, kuriuos galima groti tuo pačiu metu, skaičių.

Sukurkite pavyzdį

Šį kartą garso efektas bus paleistas kiekvieną kartą, kai spustelėsite mygtuką, todėl sukurkite vartotojo sąsają, kaip parodyta paveikslėlyje. Detalės yra tinkamos ir geros.

Numeskite ir pridėkite garso failą, kurį norite paleisti į savo projektą.

Iki paskutinio karto standartinė funkcija AudioSource buvo įtraukta į hierarchiją, Šį kartą pridėsime scenarijų, nes valdysime patys. SoundPlayManager Palikite pavadinimą kaip .

Sukurkite scenarijų taip:

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

Kadangi scenarijus yra ilgas, išsamus paaiškinimas praleidžiamas, tačiau jis turi šias funkcijas.

  • AudioClip Galite leisti garsą praeidami
  • Kai to paties tipo garsas grojamas vienas ant kito, jei bandote atkurti daugiau nei tam tikrą balsų skaičių, senieji atkūrimo duomenys sustoja (pradinė vertė yra iki 2 atkūrimų).
  • Persidengiantis atkūrimas tame pačiame kadre neleidžiamas

Tai neleidžia didėti garsumui, kai tas pats garsas atkuriamas atgal. Kalbant apie funkcionalumą, įtrauktas tik minimalus, todėl, jei reikia, pridėkite jį.

Scenarijus pridėtas prie "EventSystem".

Tada sukurkite mygtuko scenarijų.

Sukurkite scenarijų taip:

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

Atkūrimo procesą atlieka pats savadarbis SoundPlayManager , todėl mygtuko įvykyje tiesiog perduokite garso duomenis ir paleiskite juos.

Scenarijus pridėtas prie "EventSystem". Priedų valdymas nėra pagrindinė šių patarimų tema, todėl ji yra tinkama.

Garso įraše nustatykite, kad garso failas būtų leidžiamas. Nustatykite "Sound Play Manager" į objektą, SoundPlayManager prie kurio pridedate. Kadangi esame prisirišę prie EventSystem, nustatysime EventSystem.

Galiausiai priskirkite mygtukui OnClick paspaudimo įvykį.

Baigę paleiskite žaidimą. Pagal numatytuosius nustatymus maksimalus vienu metu grojamų žmonių skaičius yra 2, todėl dar kartą spustelėkite mygtuką, kol groja du garsai, ir įsitikinkite, kad pirmasis garsas išnyksta.

Šį kartą sukurta programa turi viršutinę kiekvieno tipo garso atkūrimo laiko ribą, todėl ji skamba natūraliai, net jei susipinate kitus garso efektus. Tačiau, atsižvelgiant į garso tipą, viršutinė 2 riba gali būti nepakankama, todėl gali būti naudinga nustatyti viršutinę ribą kiekvienam garso tipui. Na, aš nežinau, ar yra tokia galimybė sluoksniuoti garsą, bet ...