동시에 재생되는 음향 효과의 수를 제어합니다

페이지 업데이트 :
페이지 생성 날짜 :

검증 환경

윈도우
  • 윈도우 11
Unity 에디터
  • 2021.3.3f1
입력 시스템 패키지
  • 1.3.0

이 팁의 전제 조건

이 팁에 대한 설명의 전제로 다음 설정이 미리 이루어졌습니다.

샘플에 포함 된 재료에 대해

음향 효과는 다음 사이트에서 차용합니다.

오디오 파일 정보

Unity의 표준 기능으로 재생할 수 있는 오디오 파일 포맷은 다음과 같습니다. 이 팁에서 사용되기 때문에 미리 준비하십시오.

  • WAV (.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의 상한이 부족할 수 있으므로, 소리의 종류마다 상한을 설정할 수 있으면 좋을지도 모릅니다. 글쎄, 소리를 레이어링 할 수있는 기회가 있는지 모르겠지만 ...