एक साथ बजाए जाने वाले ध्वनि प्रभावों की संख्या को नियंत्रित करें

पेज अद्यतन :
पेज निर्माण की तारीख :

सत्यापन वातावरण

विंडोज़
  • विंडोज 11
एकता संपादक
  • 2021.3.3f1
इनपुट सिस्टम पैकेज
  • 1.3.0

इस टिप के लिए आवश्यक शर्तें

इस टिप के विवरण के लिए एक आधार के रूप में निम्नलिखित सेटिंग्स पहले से बनाई गई हैं।

नमूने के साथ शामिल सामग्री के बारे में

ध्वनि प्रभाव निम्नलिखित साइटों से उधार लिए गए हैं।

ऑडियो फ़ाइलों के बारे में

निम्नलिखित ऑडियो फ़ाइल स्वरूपों को यूनिटी की मानक सुविधाओं के साथ खेला जा सकता है: कृपया इसे पहले से तैयार करें क्योंकि इसका उपयोग इन युक्तियों में किया जाएगा।

  • WAV (.wav)
  • OggVorbis (.ogg)
  • एमपीईजी परत 3 (.mp3)

अधिक जानकारी के लिए, आधिकारिक एकता दस्तावेज़ देखें।

एक साथ कई ऑडियो प्लेबैक की ऊपरी सीमा और मात्रा के बारे में

पिछले सुझावों में, AudioClip अब ऑडियो डेटा तैयार AudioSource.PlayOneShot करते समय उन्हें चलाकर कई आवाजों को चलाना संभव है। हालांकि, खेले जा सकने वाले खेलों की संख्या की कोई सीमा नहीं है, इसलिए यदि आप इसे खेल के दौरान सीमित नहीं करते हैं, तो बहुत अधिक ध्वनि खेली जा सकती है और एक तेज मात्रा खेली जा सकती है।

यहां मैं अपना खुद का प्रोग्राम बनाना चाहता हूं और ध्वनि प्रभावों की संख्या को नियंत्रित करना चाहता हूं जिन्हें एक ही समय में खेला जा सकता है।

नमूना बनाएँ

इस बार, हर बार जब आप बटन पर क्लिक करते हैं तो ध्वनि प्रभाव चलेंगे, इसलिए चित्र में दिखाए गए अनुसार यूआई बनाएं। विवरण उपयुक्त और अच्छे हैं।

उस ऑडियो फ़ाइल को छोड़ दें और जोड़ें जिसे आप अपने प्रोजेक्ट में खेलना चाहते हैं।

पिछली बार तक, मानक फ़ंक्शन 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 प्लेबैक तक है)।
  • एक ही फ्रेम पर ओवरलैपिंग प्लेबैक की अनुमति नहीं है।

यह वॉल्यूम को बढ़ने से रोकता है जब एक ही ऑडियो को बैक-टू-बैक चलाया जाता है। कार्यक्षमता के संदर्भ में, केवल न्यूनतम शामिल है, इसलिए यदि आपको इसकी आवश्यकता हो तो कृपया इसे जोड़ें।

स्क्रिप्ट इवेंट सिस्टम से जुड़ा हुआ है।

इसके बाद, बटन के लिए एक स्क्रिप्ट बनाएं।

स्क्रिप्ट निम्नानुसार बनाएँ:

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 स्वयं द्वारा की जाती है, इसलिए बटन इवेंट में, बस ऑडियो डेटा पास करें और इसे चलाएं।

स्क्रिप्ट इवेंट सिस्टम से जुड़ा हुआ है। संलग्न प्रबंधन इस युक्तियों का मुख्य विषय नहीं है, इसलिए यह उचित है।

ऑडियो क्लिप के लिए, ऑडियो फ़ाइल को चलाने के लिए सेट करें। ध्वनि प्ले प्रबंधक को उस ऑब्जेक्ट पर SoundPlayManager सेट करें जिससे आप अनुलग्न कर रहे हैं. चूंकि हम इवेंट सिस्टम से जुड़ रहे हैं, इसलिए हम इवेंट सिस्टम सेट करेंगे।

अंत में, बटन क्लिक ईवेंट को OnClick असाइन करें।

जब आप काम पूरा कर लें तो गेम चलाएं। डिफ़ॉल्ट रूप से, एक साथ नाटकों की अधिकतम संख्या 2 पर सेट है, इसलिए कृपया दो ध्वनियों के चलने के दौरान बटन पर फिर से क्लिक करें और सुनिश्चित करें कि पहली ध्वनि गायब हो जाती है।

इस बार बनाए गए प्रोग्राम में प्रत्येक प्रकार की ध्वनि के लिए प्लेबैक समय की संख्या पर एक ऊपरी सीमा है, इसलिए यह स्वाभाविक लगता है, भले ही आप अन्य ध्वनि प्रभावों को आपस में जोड़ते हों। हालांकि, ध्वनि के प्रकार के आधार पर, 2 की ऊपरी सीमा पर्याप्त नहीं हो सकती है, इसलिए प्रत्येक प्रकार की ध्वनि के लिए ऊपरी सीमा निर्धारित करने में सक्षम होना एक अच्छा विचार हो सकता है। खैर, मुझे नहीं पता कि ध्वनि को परत करने का ऐसा अवसर है या नहीं, लेकिन ...