동시에 재생되는 음향 효과의 수를 제어합니다
검증 환경
- 윈도우
-
- 윈도우 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의 상한이 부족할 수 있으므로, 소리의 종류마다 상한을 설정할 수 있으면 좋을지도 모릅니다. 글쎄, 소리를 레이어링 할 수있는 기회가 있는지 모르겠지만 ...