Toistettujen samanaikaisten äänitehosteiden määrän hallinta

Sivu päivitetty :
Sivun luontipäivämäärä :

Varmennusympäristö

Windows
  • Windows 11
Unity-editori
  • 2021.3.3F1
Syöttöjärjestelmän paketti
  • 1.3.0

Tämän vinkin edellytykset

Seuraavat asetukset on tehty etukäteen tämän vinkin kuvauksen lähtökohtana.

Tietoja näytteeseen sisältyvästä materiaalista

Äänitehosteet on lainattu seuraavilta sivustoilta.

Tietoja äänitiedostoista

Seuraavia äänitiedostomuotoja voidaan toistaa Unityn vakio-ominaisuuksilla: Valmistele se etukäteen, koska sitä käytetään näissä vinkeissä.

  • WAV (.wav)
  • OggVorbis (.ogg)
  • MPEG-kerros 3 (.mp3)

Lisätietoja on virallisissa Unity-dokumentaatiossa.

Tietoja useiden samanaikaisten äänentoistojen ylärajasta ja äänenvoimakkuudesta

Edellisissä vinkeissä AudioClip on nyt mahdollista toistaa useita ääniä toistamalla niitä valmistellessasi AudioSource.PlayOneShot äänidataa . Pelattavien pelien määrää ei kuitenkaan ole rajoitettu, joten jos et rajoita sitä pelin aikana, voidaan toistaa paljon ääntä ja kovaa äänenvoimakkuutta.

Täällä haluaisin luoda oman ohjelman ja hallita samanaikaisesti toistettavien äänitehosteiden määrää.

Mallin luominen

Tällä kertaa äänitehoste toistetaan aina, kun napsautat painiketta, joten luo käyttöliittymä kuvan osoittamalla tavalla. Yksityiskohdat ovat asianmukaisia ja hyviä.

Pudota ja lisää toistettava äänitiedosto projektiisi.

Viime aikaan asti hierarkiaan lisättiin vakiotoiminto AudioSource , Tällä kertaa lisäämme käsikirjoituksen, koska laitamme oman hallintamme. SoundPlayManager Jätä nimeksi .

Luo komentosarja seuraavasti:

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

Koska komentosarja on pitkä, yksityiskohtainen selitys jätetään pois, mutta sillä on seuraavat toiminnot.

  • AudioClip Voit toistaa ääntä ohittamalla
  • Kun samantyyppistä ääntä toistetaan päällekkäin, jos yrität toistaa enemmän kuin tietyn määrän ääniä, vanhat toistotiedot pysähtyvät (alkuarvo on enintään 2 toistoa).
  • Päällekkäinen toisto samassa kehyksessä ei ole sallittua

Tämä estää äänenvoimakkuuden kasvamisen, kun samaa ääntä toistetaan peräkkäin. Toiminnallisuuden suhteen vain vähimmäismäärä on mukana, joten lisää se, jos tarvitset sitä.

Skripti on liitetty EventSystemiin.

Luo seuraavaksi komentosarja painikkeelle.

Luo komentosarja seuraavasti:

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

Toistoprosessin tekee itse tekemänsä SoundPlayManager , joten painiketapahtumassa vain siirrä äänidata ja toista se.

Skripti on liitetty EventSystemiin. Liitä hallinta ei ole tämän vinkin pääaihe, joten se on tarkoituksenmukaista.

Aseta äänileikkeelle toistettava äänitiedosto. Aseta Sound Play Manager objektiin SoundPlayManager , johon olet liittämässä. Koska liitymme EventSystemiin, asetamme EventSystemin.

Määritä lopuksi painikkeen napsautustapahtuma OnClick .

Suorita peli, kun olet valmis. Oletuksena samanaikaisten toistojen enimmäismäärä on 2, joten napsauta painiketta uudelleen kahden äänen toiston aikana ja varmista, että ensimmäinen ääni katoaa.

Tällä kertaa luodulla ohjelmalla on yläraja kunkin äänityypin toistoaikojen määrälle, joten se kuulostaa luonnolliselta, vaikka yhdistäisit muita äänitehosteita. Äänityypistä riippuen yläraja 2 ei kuitenkaan välttämättä riitä, joten voi olla hyvä idea pystyä asettamaan yläraja jokaiselle äänityypille. No, en tiedä, onko äänen kerrostamiseen tällainen mahdollisuus, mutta ...