Controlați numărul de efecte sonore redate simultan

Pagina actualizată :
Data creării paginii :

Mediul de verificare

Windows
  • Ferestre 11
Unity Editor
  • 2021.3.3F1
Pachet sistem de intrare
  • 1.3.0

Cerințe preliminare pentru acest sfat

Următoarele setări au fost făcute în avans ca premisă pentru descrierea acestui sfat.

Despre materialul inclus în eșantion

Efectele sonore sunt împrumutate de pe următoarele site-uri.

Despre fișierele audio

Următoarele formate de fișiere audio pot fi redate cu caracteristicile standard ale Unity: Vă rugăm să-l pregătiți în avans, deoarece va fi folosit în aceste sfaturi.

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

Pentru mai multe informații, consultați documentația oficială a Unității.

Despre limita superioară și volumul redării audio simultane multiple

În sfaturile anterioare, AudioClip acum este posibil să redați mai multe voci redându-le în timp ce pregătiți AudioSource.PlayOneShot datele audio în . Cu toate acestea, nu există nicio limită a numărului de jocuri care pot fi jucate, deci dacă nu îl limitați în timpul jocului, poate fi redat mult sunet și poate fi redat un volum puternic.

Aici aș dori să-mi creez propriul program și să controlez numărul de efecte sonore care pot fi redate în același timp.

Crearea eșantionului

De data aceasta, efectul sonor va fi redat de fiecare dată când faceți clic pe buton, deci creați interfața de utilizare așa cum se arată în figură. Detaliile sunt adecvate și bune.

Fixați și adăugați fișierul audio pe care doriți să îl redați în proiectul dvs.

Până ultima dată, funcția AudioSource standard a fost adăugată la ierarhie, De data aceasta, vom adăuga un script pentru că ne vom pune propriul control. SoundPlayManager Lăsați numele ca .

Creați scriptul după cum urmează:

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

Deoarece scriptul este lung, explicația detaliată este omisă, dar are următoarele funcții.

  • AudioClip Puteți reda conținut audio trecând
  • Când același tip de sunet este redat unul peste celălalt, dacă încercați să redați mai mult de un anumit număr de voci, vechile date de redare se opresc (valoarea inițială este de până la 2 redări).
  • Redarea suprapusă la același cadru nu este permisă

Acest lucru împiedică creșterea volumului atunci când același sunet este redat unul după altul. În ceea ce privește funcționalitatea, este inclus doar minimul, așa că vă rugăm să îl adăugați dacă aveți nevoie.

Scriptul este atașat la EventSystem.

Apoi, creați un script pentru buton.

Creați scriptul după cum urmează:

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

Procesul de redare se face de către SoundPlayManager sine, așa că în evenimentul butonului, trebuie doar să treceți datele audio și să le redați.

Scriptul este atașat la EventSystem. Gestionarea atașării nu este subiectul principal al acestor sfaturi, deci este adecvat.

Pentru clipul audio, setați fișierul audio de redat. Setați Managerul de redare a sunetului SoundPlayManager la obiectul la care atașați. Deoarece ne atașăm la EventSystem, vom seta EventSystem.

În cele din urmă, atribuiți butonului faceți clic pe OnClick eveniment.

Rulați jocul când ați terminat. În mod implicit, numărul maxim de redări simultane este setat la 2, așa că faceți clic din nou pe buton în timp ce se redau două sunete și asigurați-vă că primul sunet dispare.

Programul creat de data aceasta are o limită superioară a numărului de timpi de redare pentru fiecare tip de sunet, deci sună natural chiar dacă împletiți alte efecte sonore. Cu toate acestea, în funcție de tipul de sunet, este posibil ca limita superioară de 2 să nu fie suficientă, deci poate fi o idee bună să puteți seta o limită superioară pentru fiecare tip de sunet. Ei bine, nu știu dacă există o astfel de oportunitate de a stratifica sunetul, dar ...