Categories: Unity

Unity:複数のオーディオクリップを順番に再生して再生時間をバーで表示

今回は複数のオーディオクリップを順番に再生する手順を試してみました。

アセットストアから Seamless Loop and Short Music をダウンロード

まずはアセットストアから無料のオーディオアセット Seamless Loop and Short Music をダウンロード。

収録内容は、短いシームレスなループのオーディオクリップが19ファイル(OGG形式)と…

繰り返しで構成されたオーディオクリップが24ファイル(OGGとMP3形式混在)あります。

デモシーンとしてプレイヤーのシーンが含まれていて、オーディオクリップの再生制御の勉強にもなります。

シーンを開いて[Inspector]ウィンドウでスクリプトコンポーネントを確認すると、このように配列に収録ファイルが入っています。

シーンの作成

まずはシーンを作成します。今回は2Dシーンなのでライトオブジェクトは削除して Main Camera コンポーネントの Projection > Orthographic に変更しました。

必要なUIオブジェクトを配置。[Game]ビューはこんな感じになりました。

オーディオクリップを順番に再生するスクリプト

次にスクリプトを作成します。主な処理はこのような感じです。

  • オーディオクリップを配列に格納
  • 配列に格納されたオーディオクリップの長さを取得してコルーチンで再生時間を制御
  • 再生が終わると次のオーディオクリップを再生
  • オーディオクリップの長さと再生時間を UI Image コンポーネントの幅の値に変換して表示
  • オーディオクリップのファイル名を取得して UI Text コンポーネントで表示
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
// UI処理のクラスを使用する宣言
using UnityEngine.UI;
// AudioSource コンポーネントを要求(自動的にアタッチされる)
[RequireComponent(typeof(AudioSource))]

public class AudioPlayer : MonoBehaviour
{
    // AudioSource コンポーネントを格納する変数
    private AudioSource audioSource;
    // AudioClip を格納する配列のインデックス番号
    private int index = 0;
    // AudioSource の再生中確認フラグ
    private bool isPlaying;
    // 再生バー:UI Image コンポーネントを格納する変数
    public Image image;
    // オーディオクリップタイトル:UI Text コンポーネントを格納する変数
    public Text audioClipTitle;
    // ボリューム:UI Slider コンポーネントを格納する変数
    public Slider slider;
    // 一時停止:UI Image コンポーネントを格納する変数
    public Image imagePause;
    // オーディオクリップの長さを再生バーの幅の値に変換した値を格納する変数
    private float playBarWidth;
    // オーディオクリップの現在の再生時間を再生バーの幅の値に変換した値を格納する変数
    private float playBarNowWidth;
    // AudioClip を格納する配列
    public AudioClip[] audioClip;

    // ゲーム開始時の処理
    private void Start()
    {
        // AudioSource コンポーネントを変数 audio に格納
        audioSource = FindObjectOfType<AudioSource>();
        // AudioSource コンポーネントの mute を true に設定
        audioSource.mute = true;
        // UI Slider コンポーネントの値を AudioSource コンポーネントの volume に設定
        audioSource.volume = slider.value;
        // UI Image の幅の値を変数 playBarWidth に格納
        playBarWidth = image.rectTransform.sizeDelta.x;
        // 一時停止の UI Image コンポーネントを無効にする
        imagePause.enabled = false;
    }

    // ゲーム実行中の毎フレーム処理
    private void Update()
    {
        // AudioSource の再生中確認フラグが false であれば
        if (!isPlaying)
        {
            // コルーチン AudioPlay を実行       
            StartCoroutine("AudioPlay");
        }
        // オーディオクリップの長さをUI Image の幅に換算し、現在再生時間に変えた値を変数 playBarNowWidth に格納
        playBarNowWidth = (playBarWidth / audioClip[index].length) * audioSource.time;
        //変数 playBarNowWidth の値を使用して UI Image コンポーネントの RectTransform の幅サイズを指定
        image.rectTransform.sizeDelta = new Vector2(playBarNowWidth, image.rectTransform.sizeDelta.y);
    }

    // コルーチン:オーディオ再生
    IEnumerator AudioPlay()
    {
        // フラグ isPlaying が true の場合
        isPlaying = true;
        //繰り返し処理:配列に格納されたオーディオクリップの数だけ繰り返す
        for (index = 0; index < audioClip.Length; index++)
        {
            // 再生するオーディオクリップを配列から指定する
            audioSource.clip = audioClip[index];
            // オーディオクリップを再生
            audioSource.Play();
            // オーディオクリップタイトルのUI Text コンポーネントに順番とタイトルを格納
            audioClipTitle.text = (index + 1) + "/" + audioClip.Length + ": " + audioClip[index].name;
            // オーディオクリップの再生が終了するまで
            yield return new WaitForSeconds(audioClip[index].length);
        }
        // フラグ isPlaying を false のに設定
        isPlaying = false;
    }

    // UI ボタンクリックで実行:再生一時停止処理
    public void onClickPause()
    {
        // AudioSource が再生中の場合
        if (audioSource.isPlaying)
        {
            // 再生を一時停止
            audioSource.Pause();
            // 一時停止の UI Image コンポーネントを有効にする
            imagePause.enabled = true;
        }
        // AudioSource が一時停止中の場合
        else if (!audioSource.isPlaying)
        {
            // 一時停止を解除
            audioSource.UnPause();
            // 一時停止の UI Image コンポーネントを無効にする
            imagePause.enabled = false;
        }
    }
}

スクリプト AudioPlayer コンポーネントの設定

[Hierarchy]ウィンドウ > [Create]ボタン > Create Empty を選択。オブジェクト名を Audio Player に変更。作成したスクリプト Audio Player をアタッチ。自動的に AudioSource コンポーネントがアタッチされます。 [Inspector]ウィンドウで確認するとこのようになっています。

変数フィールドにそれぞれ必要なオブジェクトをドラッグ&ドロップで割り当てます。配列 Audio Clip には無料のオーディオアセット Seamless Loop and Short Music からショートループのファイル19ファイルを登録しました。

今回の処理の問題点

再生中に一時停止をした場合、コルーチンの WaitForSeconds でオーディオクリップの再生時間を制御しており一時停止中の時間を考慮していません。なので再生を再開すると、再生途中で次の曲に切り替わってしまいます。

再生時間の制御をオーディオクリップの長さと再生時間を比較する条件で行えば大丈夫そうな気がしますが…今後の課題として保留したいと思います。

WebGL

今回の内容をWebGLでビルドしてみました。画像クリックでファイルがダウンロード、再生されます。スタート時はオーディオミュートにしています。画面右下のボタンでミュート解除できます。(ダウンロードサイズ:約17MB)

参考:Unity スクリプトリファレンス

AudioSource.clip – Unity スクリプトリファレンス

corevale