複数のBGMを切り替えられるようにしたよ | Unity

9時~10時はこの音楽が流れる、9時~10時はこの音楽が流れる、みたいな音楽時計てきなやつを作っています。前回はボタンを押すとBGMが鳴ったり止まったりするようにしたので、今日はボタンを押すと複数のBGMを切り替えられるようにしました。記録日記です。

複数曲入れる枠を作る

先日書いたBgmControllerでは、BGMオブジェクトを指定して曲を流しています。

でもBGMオブジェクトには曲が1曲しか入ってないし、そもそも曲を入れる枠が1つしかなくて、複数曲設定できません。

ということで、BgmControllerに複数曲設定できるように枠を増築します。

前回書いたコードの冒頭のところに一行追記して、曲を複数入れられるaudioClips変数をつくります。

using UnityEngine;
using TMPro;

public class BgmController : MonoBehaviour
{
    [SerializeField] private AudioSource audioSource;
    [SerializeField] private AudioClip[] audioClips;    // ←追記(曲を複数入れられる枠)
    [SerializeField] private TextMeshProUGUI playButtonText;
  
 // 以下略

保存してUnityに戻り、ヒエラルキーのBGMを選択すると、インスペクターのBgm ControllerにaudioClipsが表示されています。この右側にあるテキストボックス(はじめは0になってる)に4と入力。左側の三角をクリックするとElement 0~3 が表示されてるので、プロジェクトタブからElement 0~3の枠に曲のファイルをドラッグ&ドロップ。4曲はいったよー

Audio Source内のAudio Resourceに曲が入ったままになっているので消します。

曲を切り替えるボタンを作る

次に送るボタンと前に送る(戻す?)ボタンを追加していきます。ボタンの2つのボタンを追加します。ヒエラルキーのPlayButtonを右クリックして複製。名前を下記に変更。

  • PlayButton(1)→NextButton、その中にあるPlayButtonText→NextButtonText
  • PlayButton(2)→PrevButton、その中にあるPlayButtonText→PrevButtonText

ボタンの位置を変更します。別にどこでもいいんですが、今回はいい感じに真ん中に並ぶようにしてみます。ヒエラルキーでNextButtonを選択した状態で、インスペクターのRect TransformにあるPoz Xに90と入力。PrevButtonも同じように、こちらは-90と入力します。

ボタンの表示内容も変更します。ヒエラルキーでNextButtonTextを選択した状態で、インスペクターの中にTextMeshPro-Text(UI)があるので、この中のText Inputに>>と入力。PrevButtonTextも同じように、こちらは<<と入力します。

これでボタンができたよ! わーい

曲を切り替えるスクリプトを書く

前回書いたスクリプトBgmControllerをいじって、曲が切り替わるようにします。

今回書いたのはこれだ!!

using UnityEngine;
using TMPro;

public class BgmController : MonoBehaviour
{
    [SerializeField] private AudioSource audioSource;   // AudioSourceコンポーネント
    [SerializeField] private AudioClip[] audioClips;    // オーディオクリップ
    [SerializeField] private TextMeshProUGUI playButtonText;    // ボタンのテキストオブジェクト
    private int currentAudioClipIndex;  // 現在の曲のインデックス番号

    // Start is called once before the first execution of Update after the MonoBehaviour is created
    void Start()
    {
        if (!audioSource) audioSource = GetComponent<AudioSource>();    // AudioSourceコンポーネントを取得
        if (audioClips == null || audioClips.Length == 0) return;       // audioClipsがなければ中断

        currentAudioClipIndex = 0;  // 初期値
        audioSource.clip = audioClips[currentAudioClipIndex];   // 最初の曲をセット
        UpdatePlayButtonUI();       // ボタンの表示を更新
    }

    // 再生/一時停止
    public void PauseIfPlayingElsePlay()
    {
        // 再生中の場合は一時停止、一時停止中の場合は再生する
        if (audioSource.isPlaying)
            PauseAndRefresh();
        else
            PlayAndRefresh();
    }

    // 再生してUI更新
    private void PlayAndRefresh()
    {
        audioSource.Play();     // 再生
        UpdatePlayButtonUI();   // ボタンの表示を更新
    }

    // 一時停止してUI更新
    private void PauseAndRefresh()
    {
        audioSource.Pause();    // 一時停止
        UpdatePlayButtonUI();   // ボタンの表示を更新
    }

    // 1曲進む
    public void Next()
    {
        ShiftTrack(1);  // 次の曲へ
    }

    // 1曲戻る
    public void Prev()
    {
        ShiftTrack(-1);  // 前の曲へ
    }

    // 再生状態を保ったまま曲送り
    private void ShiftTrack(int offset)
    {
        if (audioClips == null || audioClips.Length == 0) return;   // audioClipsに1曲もなければ中断
        bool wasPlaying = audioSource.isPlaying;    // 再生中だったかどうかチェック
        ApplyTrackOffset(offset);           // offset分だけ曲を進めてclip更新
        if (wasPlaying) PlayAndRefresh();   // 再生中だった場合は再生
        UpdatePlayButtonUI();               // ボタンの表示を更新
    }

    // offset分だけ曲を進めてclip更新
    private void ApplyTrackOffset(int offset)
    {
        currentAudioClipIndex += offset;        // currentAudioClipIndexにoffsetを加算
        currentAudioClipIndex = (currentAudioClipIndex + audioClips.Length) % audioClips.Length;    // 循環インデックス処理 ※currentAudioClipIndexをAudioClipsの範囲内にする
        audioSource.clip = audioClips[currentAudioClipIndex];   // currentAudioClipIndex番目の曲を現在の曲に設定
    }

    // ボタンの表示を更新
    private void UpdatePlayButtonUI()
    {
        if (!playButtonText) return;    // テキストオブジェクトが設定されていなければ中断
        playButtonText.text = audioSource.isPlaying ? "Pause" : "Play"; // 再生中の場合はテキストをPause、再生中でない場合はPlayに設定
    }
}

UpdatePlayButtonUIの変数名など、関係ないところも少し変えました。

ボタンクリック時にスクリプトを呼び出せるようにする

ボタンを押したときにスプリクトを呼び出せるように、ボタン側の設定をします。

ヒエラルキーでPrevButtonを選択してインスペクターを見ると、下の方にあるクリック時 () のところにPauseIfPlayingElsePlayが入っています。これをBgmController.Prevに変更。

同じようにヒエラルキーでNextButtonを選択して、こちらはBgmController.Nextに変更しておきます。

これでOK。ゲーム再生ボタンをクリックして、Playボタンで再生・一時停止、>>ボタンと<<ボタンで曲送りができるようになっています。

今回はここまで

前回予定していた制作の流れは下記のような感じでした。

  1. BGM鳴らす
  2. ボタンを押すとBGMが鳴ったり止まったりするようにする
  3. ボタンを押すと複数のBGMを切り替えられるようにする(今回はここ)
  4. 時間を表示できるようにする
  5. 時間によってBGMを切り替えて鳴らせるようにする
  6. 時間によってBGMを鳴らす機能のオンオフができるようにする

今回は3をやったので、次回は4.時間の表示をやっていこうと思います。

  • 0
  • 0
  • 0

きやけ

いろんなものをちょっとずつかじって、結局よくわからない人です。ときどきなにかをつくります。

作者のページを見る

寄付について

「novalue」は、‟一人ひとりが自分らしく働ける社会”の実現を目指す、
就労継続支援B型事業所manabyCREATORSが運営するWebメディアです。

当メディアの運営は、活動に賛同してくださる寄付者様の協賛によって成り立っており、
広告記事の掲載先をお探しの企業様や寄付者様を随時、募集しております。

寄付についてのご案内