کنترل تعداد جلوه های صوتی همزمان پخش شده

صفحه به روز شده :
تاریخ ایجاد صفحه :

محیط تایید

ویندوز
  • ویندوز 11
ویرایشگر یونیتی
  • دانلود: 2021.3.3f1
بسته سیستم ورودی
  • 1.3.0

پیشنیازهای این نکته

تنظیمات زیر از قبل به عنوان یک فرض برای توصیف این نکته ساخته شده است.

درباره مواد همراه با نمونه

جلوه های صوتی از سایت های زیر قرض گرفته شده است.

درباره فایل های صوتی

فرمت های فایل های صوتی زیر را می توان با ویژگی های استاندارد Unity بازی کرد: لطفا ان را از قبل اماده کنید زیرا در این نکات استفاده خواهد شد.

  • پنل های ال سی (.wav)
  • اگ ووربیس (.ogg)
  • MPEG لایه 3 (.mp3)

برای اطلاعات بیشتر، مستندات رسمی Unity را ببینید.

درباره حد بالایی و حجم پخش صوتی همزمان چندگانه

در نکات قبلی، AudioClip در حال حاضر امکان پخش چندین صدا با پخش انها در هنگام اماده سازی داده های AudioSource.PlayOneShot صوتی در . با این حال، هیچ محدودیتی برای تعداد بازی هایی که می توانند بازی کنند وجود ندارد، بنابراین اگر ان را در طول بازی محدود نکنید، ممکن است صدای زیادی پخش شود و حجم صدای بلند ممکن است پخش شود.

در اینجا من می خواهم برای ایجاد برنامه خود من و کنترل تعدادی از جلوه های صوتی است که می تواند در همان زمان بازی.

ایجاد نمونه

این بار، جلوه صوتی هر بار که روی دکمه کلیک می کنید پخش می شود، بنابراین UI را همانطور که در شکل نشان داده شده است ایجاد کنید. جزئیات مناسب و خوب است.

فایل صوتی را که می خواهید در پروژه خود پخش کنید رها کنید و اضافه کنید.

تا اخرین بار، تابع AudioSource استاندارد به سلسله مراتب اضافه شد، این بار، ما یک اسکریپت اضافه خواهیم کرد زیرا ما کنترل خودمان را قرار خواهیم داد. SoundPlayManager نام را به عنوان .

ایجاد اسکریپت به شرح زیر است:

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

از انجا که فیلمنامه طولانی است، توضیح دقیق حذف می شود، اما عملکردهای زیر را دارد.

  • AudioClip شما می توانید صدا را با عبور پخش کنید
  • هنگامی که یک نوع صدا در بالای یکدیگر پخش می شود، اگر سعی کنید بیش از تعداد مشخصی از صداها را پخش کنید، داده های پخش قدیمی متوقف می شود (مقدار اولیه تا 2 پخش است).
  • پخش همپوشانی در همان چارچوب مجاز نیست

این مانع از افزایش حجم صدا می شود زمانی که همان صدا پشت سر هم پخش می شود. از نظر عملکرد، تنها حداقل گنجانده شده است، بنابراین لطفا ان را اضافه کنید اگر شما به ان نیاز دارید.

این اسکریپت به EventSystem متصل شده است.

بعد، یک اسکریپت برای دکمه ایجاد کنید.

ایجاد اسکریپت به شرح زیر است:

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

فرایند پخش توسط خود ساخته SoundPlayManager انجام می شود، بنابراین در رویداد دکمه، فقط داده های صوتی را منتقل کنید و ان را پخش کنید.

این اسکریپت به EventSystem متصل شده است. مدیریت ضمیمه موضوع اصلی این نکات نیست، بنابراین مناسب است.

برای کلیپ صوتی، فایل صوتی را برای پخش تنظیم کنید. مدیر پخش صدا را روی شیئی که به SoundPlayManager ان متصل می شوید تنظیم کنید. از انجا که ما در حال اتصال به EventSystem هستیم، EventSystem را تنظیم خواهیم کرد.

در نهایت، به رویداد کلیک دکمه اختصاص دهید OnClick .

وقتی کارتان تمام شد بازی را اجرا کنید. به طور پیش فرض، حداکثر تعداد پخش همزمان به 2 تنظیم می شود، بنابراین لطفا دوباره روی دکمه کلیک کنید در حالی که دو صدا در حال پخش هستند و مطمئن شوید که صدای اول ناپدید می شود.

برنامه ایجاد شده در این زمان دارای محدودیت بالایی در تعداد زمان پخش برای هر نوع صدا است، بنابراین طبیعی به نظر می رسد حتی اگر جلوه های صوتی دیگر را در هم قرار دهید. با این حال، بسته به نوع صدا، حد بالایی 2 ممکن است کافی نباشد، بنابراین ممکن است ایده خوبی باشد که بتوانید حد بالایی را برای هر نوع صدا تعیین کنید. خوب، من نمی دانم اگر چنین فرصتی برای لایه صدا وجود دارد، اما ...