tanaka's Programming Memo

プログラミングについてのメモ。

Unityで簡易にBGMと効果音を鳴らす

UnityでささっとBGMや効果音を鳴らす方法です。

  • 音源データの書式の説明が古くなっていたので修正(2022/7/2)
  • 列挙子などの名前をパスカルケースに変更(2021/6/28)

目次

前提

Unityでとりあえず手っ取り早くBGMや効果音を鳴らしたい!というためのサンプルコードと手順です。機能は以下の通りです。

  • BGM
    • シーンごとに、設定したBGMを再生します
    • BGMをループ再生できます
    • 同じシーン内で曲は変えません
    • シーンを跨いだBGMの再生には対応しません
  • SE
    • 1つのオブジェクトですべての効果音を再生します
    • 3Dサウンドは使いません

プロジェクトの準備

Unity2019.1.5での実装例です。

  • Unityでプロジェクトを新規に作るか、音を鳴らしたいプロジェクトを開きます
  • 利用したい音源データ(oggmp3wavなど)を用意したら、Projectウィンドウの任意のフォルダーにドラッグ&ドロップしてインポートします
    • BGMをAudios/BGMフォルダー、SEをAudios/SEフォルダーにまとめた場合、以下のような感じになります

音源データのインポート

音データの種類

Unityでは色々な音声データが利用できます(オーディオファイル - Unity マニュアル)。それらのうち、主に利用するのはoggmp3wavの3種類かと思います。

oggmp3は録音したデータを圧縮したもので、やや音が劣化しますが容量が小さくなります。

(参考: oggとMP3の違いは何でしょうか?持ってるmp3の機械には対応して... - Yahoo!知恵袋)

wavは録音したデータをそのまま保存する形式です。同じ条件で録音した場合、oggmp3よりも容量が大きくなる代わりに音の劣化がありません。

Unityではプロジェクトに音源データを加えた時に内部形式に変換するので、どの形式の音源を使ってもビルドや実行時に違いはありません。

WebGL環境だとキンキンした音の最後にノイズが入ることがあります。特にwav形式で発生する印象があります。そのような場合は、以下のようなサイトで形式を変更したりすると直ることがあります。

Load Typeについて

読み込んだ音声データを選択した時にInspectorに表示される設定です。効果音やゲーム中のBGMの場合はデフォルトのままで大丈夫です。

タイトル画面やゲームオーバーなど、処理が多少重くなっても構わないようなシーンでは、Load TypeStreamingに変更すると音が鳴り始めるのが早くなる(はず)で、よさげです。

タイトルやゲームオーバー用の音源はStreamingにするとよいかも

BGMを鳴らす

BGMを鳴らします。

  • HierarchyウィンドウのCreateをクリックして、Create Emptyをクリックして空のゲームオブジェクトを作成して、名前をTinyAudioなどにします
  • InspectorウィンドウのAdd Componentをクリックして、Audio > Audio Sourceをクリックします
  • Projectウィンドウから、そのシーンで鳴らしたいBGMの音源ファイルをドラッグして、InspectorウィンドウのAudio Clip欄にドロップします

音源データをAudio Clip欄にドラッグ&ドロップ

  • BGMをループ再生したい場合は、InspectorウィンドウのLoop欄にチェックを入れます

Loop設定

以上で設定完了です。UnityをPlayするとBGMが再生されます。BGMはこれでOKです。

効果音を鳴らすためのクラスを作る

効果音はTinyAudioというクラスを作成して、スクリプトから呼び出して鳴らすようにします。

  • Hierarchyウィンドウから先ほど作成したTinyAudioオブジェクトをクリックして選択します
  • InspectorウィンドウのAdd Componentをクリックして、New scriptをクリックして、TinyAudioなどの名前でスクリプトを作ります
    • スクリプトは、Scriptsフォルダーなどを作って、そこにまとめておくのがオススメです
  • Projectウィンドウから作成したTinyAudioスクリプトをダブルクリックしてエディターで開きます
  • 以下のコードを入力、あるいはコピペします
using UnityEngine;

public class TinyAudio : MonoBehaviour
{
    public static TinyAudio Instance { get; private set; }

    /// <summary>
    /// seListに設定する効果音の種類を以下に定義します。
    /// </summary>
    public enum SE
    {
        Click,
        Hit,
        Magic
    }

    [Tooltip("効果音のAudio Clipを、SEの列挙子と同じ順番で設定してください。"), SerializeField]
    AudioClip[] seList;

    AudioSource audioSource;

    private void Awake()
    {
        Instance = this;
        audioSource = GetComponent<AudioSource>();
    }

    /// <summary>
    /// SEで指定した効果音を再生します。
    /// </summary>
    /// <param name="se">鳴らしたい効果音</param>
    public static void PlaySE(SE se)
    {
        Instance.audioSource.PlayOneShot(Instance.seList[(int)se]);
    }
}
  • 上書き保存したら、Unityに切り替えます
  • HierarchyウィンドウからTinyAudioオブジェクトをクリックして選択します
  • Projectウィンドウから効果音のファイルをドラッグして、InspectorウィンドウのSe List欄にドロップします
    • 設定する順番は、TinyAudioスクリプトSE列挙子に対応付けていきます。Clickはクリック音、Hitは攻撃音、Magicは魔法のような音ということで、その順番に設定します

AudioClipを設定

効果音を鳴らす

スクリプトからTinyAudio.PlaySE(TinyAudio.SE.Click);のように呼び出せば指定した効果音が鳴ります。TinyAudio.SE.Clickは、TinyAudio.csの10行目付近に宣言してあります。SE列挙子の最初(0番目)なので、Se ListElement 0に設定した音が鳴ります。

試しに、数字キーで効果音を鳴らす機能を実装します。

  • HierarchyウィンドウのCreateをクリックして、Create Emptyをクリックして、空のゲームオブジェクトを作成して、SETestなどの名前にします
  • InspectorウィンドウのAdd Componentをクリックして、New scriptを選択して、SETestなどの名前にします
    • SETestスクリプトは、Scriptsフォルダーに移動しておくとよいです
  • SETestスクリプトをダブルクリックして、以下のコードにします
using UnityEngine;

public class SETest : MonoBehaviour
{
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Alpha1))
        {
            TinyAudio.PlaySE(TinyAudio.SE.Click);
        }
        if (Input.GetKeyDown(KeyCode.Alpha2))
        {
            TinyAudio.PlaySE(TinyAudio.SE.Hit);
        }
        if (Input.GetKeyDown(KeyCode.Alpha3))
        {
            TinyAudio.PlaySE(TinyAudio.SE.Magic);
        }
    }
}

以上で保存して、Unityに切り替えてPlayします。数字キーの123でそれぞれ効果音が鳴ります。

数字キーを連打すると、効果音が同時に鳴ることが確認できます。今回のように音に3D空間の効果を使わない場合は、1つのAudio SourceでBGMも効果音も鳴らせます。

シーン切り替えに対応する

他のシーンでもBGMを鳴らせるようにします。

  • HierarchyウィンドウからTinyAudioオブジェクトをドラッグして、Projectウィンドウにドロップしてプレハブ化します
    • プレハブは、Prefabsなどのフォルダーを作ってまとめておくのがおススメです
  • ついでにSETestオブジェクトのドラッグ&ドロップしてプレハブ化しておきます
  • [Ctrl]+[S]キーでシーンを保存します
  • 新しいシーンを作るか、既存の別のシーンに切り替えます
  • Projectウィンドウから、TinyAudioプレハブをドラッグして、Hierarchyウィンドウにドロップします
  • 必要に応じて、ProjectウィンドウからSETestプレハブをドラッグして、Hierarchyウィンドウにドロップします(効果音の再生テストが不要な場合は不要です)
  • HierarchyウィンドウのTinyAudioオブジェクトをクリックして選択します
  • 新しいシーン用のBGMをProjectウィンドウからドラッグして、InspectorウィンドウのAudioClip欄にドロップします

BGMの音源データを設定

  • BGMをループさせたいかどうかに応じて、InspectorウィンドウのLoop欄のチェックをつけるか、外します

ループ設定

以上で完了です。PlayするとBGMが鳴ります。SETestオブジェクトを設定してあれば、数字キーの123で効果音が鳴ります。

シーンを切り替えたら、そのシーンに設定したBGMが鳴り始めます。

効果音の増やし方や変え方

効果音を増やしたり変えるには、TinyAudioクラスのSE列挙子の宣言を変更して、それに合わせてTinyAudioオブジェクトに設定する効果音リストを更新します。

  • ProjectウィンドウからTinyAudioスクリプトをダブルクリックして、エディターで開きます
  • 使いたい効果音を全て列挙子SEに定義します。例えば食べる効果音を増やしたいなら、Eatなどの名前で定義を追加します

列挙子を増やす

  • 上書き保存したらUnityに切り替えます
  • ProjectウィンドウのTinyAudioプレハブをクリックして選択します

TinyAudioプレハブを選択する

  • Projectウィンドウから追加したい音データをドラッグして、InspectorウィンドウのSe List欄にドロップするか、Sizeを増やして該当するスロットにドロップします
    • 以下、matchstick-put-fire1を追加している例です

音を追加

以上で完了です。あとはスクリプトからTinyAudio.PlaySE(TinyAudio.SE.Eat);のように呼び出すことで、新しく追加した音を鳴らすことができます。

まとめ

シーン切り替え時に効果音が途切れたり、BGMがシーンを跨げないなど気になる部分はありますが、一先ずBGMと効果音を鳴らすことができました。2DゲームやUIのシステム音など、鳴っている場所の影響を受けない音はここで紹介した以下のような方法が効率よいです。

  • BGMは、Audio SourceAudio Clip欄に音データを設定して再生
  • SEは、PlayOneShot()で再生

3D対応させたり、最初に記載したような多様な機能を実装したい場合は以下のブログなどが役に立つと思います。

kan-kikuchi.hatenablog.com

qiita.com

参考URL