【Unity】1つのオブジェクトでBGMとSEを再生してみる
今回はUnityでのBGMとSEを鳴らす処理を試してみたいと思います。
正直なところ、SEを鳴らす、BGMを鳴らすはあちこちに記事があると思います。
では、BGMを流しつつ、SEも鳴らすにはどうすれば良いのでしょうか?
シンプルなのは、BGM用のオブジェクトとSE用のオブジェクトを作成して、それぞれにAudioSourceを割り当てる方法でしょうか。
3Dの場合は、SE用のオブジェクトというよりは、音のなるオブジェクトにAudioSourceを割り当てて、SEを鳴らすのが立体音響として良いのだと思います。
ただ、2Dの場合は、そこまでやる必要が無いと思うので、1つのオブジェクトにまとめる事はできないのだろうか? と思ったので、その方法を軽く考えてみました。
結論としては、1つのオブジェクトに2つのAudioSourceを割り当てれば実現できます。
オブジェクトを用意
まずは、対象のシーンにEmptyObject
を作成します。(名前は適当に DebugScript としました。)
既にゲーム管理用のオブジェクトなどが存在するのなら、新しくEmptyObject
は作らずに、そのオブジェクトに対して以降の操作をすればOKです。
オブジェクトに2つのAudioSourceを追加
続いて、対象オブジェクトに AudioSource
を2つ追加します。
そして、追加したどちらかの AudioSource
の Loop
にチェックを入れます。こちらがBGM用のAudioSourceになります。
BGMの方は基本的に音源をループ再生すると思うので、Loopを有効にしたのですが、『このチェックの有無でどちらがBGM用かを判別する』という意図もあります。
(上の画像は最終的な状態なので、Scriptも付与されています。あと、ボタンも色々配置しています)
スクリプト作成
続いて、スクリプトを作成します。
適当にC# Script
を作成して、対象のオブジェクトに割り当てましょう。
(今回は、適当に DebugScript という名前でスクリプトを作成しました)
スクリプトの内容は以下になります。(重要な部分は、Startメソッド内の記述です)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class DebugScript : MonoBehaviour
{
[SerializeField] private AudioClip audioBGM1;
[SerializeField] private AudioClip audioBGM2;
[SerializeField] private AudioClip audioSE1;
[SerializeField] private AudioClip audioSE2;
private AudioSource audioSourceBGM;
private AudioSource audioSourceSE;
private float audioBGMVolume = 0.1f;
private float audioSEVolume = 0.5f;
void Start()
{
foreach (AudioSource audioSource in GetComponents<AudioSource>())
{
if (audioSource.loop) {
// BGM用AudioSource
audioSourceBGM = audioSource;
audioSourceBGM.volume = audioBGMVolume; // BGM音量設定
Debug.Log("Find BGM AudioSource");
}
else
{
// SE用AudioSource
audioSourceSE = audioSource;
audioSourceSE.volume = audioSEVolume; // SE音量設定
Debug.Log("Find SE AudioSource");
}
}
}
// BGM1を再生
public void OnClickPlayBGM1()
{
audioSourceBGM.clip = audioBGM1;
audioSourceBGM.Play();
}
// BGM2を再生
public void OnClickPlayBGM2()
{
audioSourceBGM.clip = audioBGM2;
audioSourceBGM.Play();
}
// BGMを停止
public void OnClickStopBGM()
{
audioSourceBGM.Stop();
}
// SE1を再生
public void OnClickPlaySE1()
{
audioSourceSE.PlayOneShot(audioSE1);
}
// SE2を再生
public void OnClickPlaySE2()
{
audioSourceSE.PlayOneShot(audioSE2);
}
}
あとは適当に…
私は、確認用にSEとBGMをそれぞれ2種類用意して、ボタンで再生制御できるようにしました。
ClipをGUI上で割り当てたり、ボタンのクリックイベントの割り当てをしたり……
必要に応じて対応して下さい。
軽くスクリプト説明
今回のポイントは Startメソッド内の記述 です。GetComponents<AudioSource>
でオブジェクトに付与されているAudioSource
を全て取得。
そして、foreachで取得したAudioSourceをBGM用かSE用か判別して保持します。if (audioSource.loop)
がその判定部分ですね。
AudioSourceを追加した時に片方だけLoopをONにしているので、ONになっている方がaudioSorceBGM
、もう1つがaudioSourceSE
として保持されます。
あとは、必要に応じて、Playだったり、PlayOneShotだったりを呼べば再生されます。
まとめ
今回はBGMとSEの再生を1つのオブジェクトで完結させる事を試してみました。
ポイントはAudioSourceを複数追加して、GetComponents<AudioSource>
で取得して、使い分ける事です。
今回はLoopをONにしている方をBGMとしましたが、1つ目に見つかった方をBGM用と決めても問題ありません。
特に何も工夫した部分はありませんが、この記事が何かのお役に立てたら嬉しいです。
ディスカッション
コメント一覧
まだ、コメントがありません