Styra antalet samtidiga ljudeffekter som spelas upp

Sidan uppdaterad :
Datum för skapande av sida :

Verifiering miljö

Windows
  • Fönster 11
Unity-redaktör
  • 2021.3.3F1
Paket för inmatningssystem
  • 1.3.0

Förutsättningar för det här tipset

Följande inställningar har gjorts i förväg som en förutsättning för beskrivningen av detta tips.

Om materialet som ingår i provet

Ljudeffekter lånas från följande webbplatser.

Om ljudfiler

Följande ljudfilformat kan spelas upp med Unitys standardfunktioner: Förbered det i förväg eftersom det kommer att användas i dessa tips.

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

Mer information finns i den officiella Unity-dokumentationen.

Om den övre gränsen och volymen för flera samtidiga ljuduppspelningar

I de tidigare tipsen AudioClip är det nu möjligt att spela flera röster genom att spela dem medan du förbereder AudioSource.PlayOneShot ljuddata i . Det finns dock ingen gräns för antalet spel som kan spelas, så om du inte begränsar det under spelet kan mycket ljud spelas och en hög volym kan spelas.

Här skulle jag vilja skapa mitt eget program och styra antalet ljudeffekter som kan spelas samtidigt.

Skapa exemplet

Den här gången spelas ljudeffekten upp varje gång du klickar på knappen, så skapa användargränssnittet enligt bilden. Detaljerna är lämpliga och bra.

Släpp och lägg till ljudfilen du vill spela upp i ditt projekt.

Fram till förra gången lades standardfunktionen AudioSource till i hierarkin, Den här gången lägger vi till ett manus eftersom vi kommer att sätta vår egen kontroll. SoundPlayManager Lämna namnet som .

Skapa skriptet på följande sätt:

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

Eftersom skriptet är långt utelämnas detaljerad förklaring, men det har följande funktioner.

  • AudioClip Du kan spela upp ljud genom att passera
  • När samma typ av ljud spelas ovanpå varandra, om du försöker spela mer än ett visst antal röster, stoppas de gamla uppspelningsdata (initialvärdet är upp till 2 uppspelningar).
  • Överlappande uppspelning i samma bildruta är inte tillåtet

Detta förhindrar att volymen ökar när samma ljud spelas upp rygg mot rygg. När det gäller funktionalitet ingår endast minimum, så lägg till det om du behöver det.

Skriptet är kopplat till EventSystem.

Skapa sedan ett skript för knappen.

Skapa skriptet på följande sätt:

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

Uppspelningsprocessen görs av den självtillverkade SoundPlayManager själv, så i knapphändelsen, skicka bara ljuddata och spela upp den.

Skriptet är kopplat till EventSystem. Bifoga hantering är inte huvudämnet för detta tips, så det är lämpligt.

För ljudklippet ställer du in ljudfilen som ska spelas upp. Ställ in Sound Play Manager på det SoundPlayManager objekt som du bifogar till. Eftersom vi ansluter till EventSystem kommer vi att ställa in EventSystem.

Slutligen tilldelar du knappklickhändelsen OnClick .

Kör spelet när du är klar. Som standard är det maximala antalet samtidiga uppspelningar inställt på 2, så klicka på knappen igen medan två ljud spelas och se till att det första ljudet försvinner.

Programmet som skapats den här gången har en övre gräns för antalet uppspelningstider för varje typ av ljud, så det låter naturligt även om du väver samman andra ljudeffekter. Beroende på typen av ljud kanske den övre gränsen på 2 inte räcker, så det kan vara en bra idé att kunna ställa in en övre gräns för varje typ av ljud. Tja, jag vet inte om det finns en sådan möjlighet att lagra ljudet, men ...