
Unityいじり日記です。
9時~10時はこの音楽が流れる、9時~10時はこの音楽が流れる、みたいな音楽時計てきなやつを作りたいです。初心者なのでステップを区切ってやっていきます。こんな感じでできてほしいです。
- BGMが鳴るようにする
- ボタンを押すとBGMが鳴ったり止まったりするようにする
- ボタンを押すと複数のBGMを切り替えられるようにする
- 時間を表示できるようにする
- 時間によってBGMを切り替えて鳴らせるようにする
- 時間によってBGMを鳴らす機能のオンオフができるようにする
スクショが英語版だったり日本語版だったりぐっちゃんぐっちゃんになっています。記事作成中にパソコンが壊れて、修理以降日本語パッチをいれてないからです。かなしい
0. Unityと音源の準備
そもそもUnityと音源が必要なので用意します。Unityインストールに関しては詳細割愛するけど、UnityのサイトからUnity Hubをインストールした後、HubからUnity本体をインストールしたよ。
Unityの用意ができたらHubから新規プロジェクトを作成。テンプレートは2Dとか3Dとか聞かれますが、今回はUniversal 3Dを選択しました。2Dのほうが軽いのかもしれない。

音源は、今回はフリー素材サイトDOVA-SYNDROMEからランダムで利用しました。個人的な勉強用とかにはいいけど、音楽時計がメインのアプリを作って他人に渡す場合は規約違反になりそう。そりゃそう。曲の切り替えを試したいのでとりあえず4曲用意。
音源ファイルを用意したら、Unityプロジェクト側にフォルダを作って格納します。プロジェクトタブのAssetsフォルダを右クリック→作成→フォルダーを選択して、フォルダ名をSoundsに変更。

Soundsフォルダができたら、Soundsフォルダに音源ファイルをドラッグ&ドロップ。音源ファイルがUnityプロジェクト側にコピーされます。


1. BGMが鳴るようにする
Unityでは音を鳴らすオブジェクトAudio Souceと音を聞くオブジェクトAudio Listenerが分かれてるらしいので、両方の設定をします。
分かれてるのは、ゲームにはプレイヤーが存在してるためみたいです。ゲームでプレイヤーが動いたとき、音と耳が分かれていれば距離によって音量を変えたりするだけでいいけど、音と耳が分かれてなかったら全部の音の設定を動かさないといけないからね。Unityが今回ほしい機能を作るのに死ぬほど向いてないことがわかりますね。
Audio Souceの設定
まず音を鳴らすオブジェクトを作ります。ヒエラルキータブの空いているスペースを右クリックして、オーディオ→オーディオソースを選択。

ヒエラルキーの中にAudio Sourceが作成されるので、名前をわかりやすいものに変更。今回はBGMにしました。

BGMのインスペクターを開きます。作成されたBGMをクリックするとインスペクタータブにBGMの情報がいろいろ表示されます。Audio Sourceの中の「オーディオソース」の横の枠に、プロジェクトタブの音源ファイルをドラッグ&ドロップ。「ゲーム開始時に再生」「ループ」のチェックボックスをオンにします。

Audio Listenerの設定
音楽を聞くオブジェクトの設定をします。ヒエラルキーのMain Cameraをクリックして、インスペクターの下の方にAudio Listenerが入っていればOK。今回は最初から設定されてました。もしなければ、「コンポーネントを追加」からAudio Listenerを検索・選択して追加したらOK。

上部のゲーム開始ボタンを押すと、ゲームが実行されます。設定した曲が流れたら成功。

ゲーム実行後は必ずゲーム停止ボタンを押しておきます。このボタンでゲームを停止しておかないと編集したものが無かったことになりかなりめんどくさい(1敗)。

2. ボタンを押すとBGMが鳴ったり止まったりするようにする
このままだと流れっぱなしなので、音楽を再生・一時停止するスクリプトを書いて、ボタンを押したときにそれを呼び出す感じにします。
ボタンを配置
ボタンのオブジェクトを作ります。ヒエラルキーの空きスペースを右クリック→UI→ボタン-TextMeshProを選択。

TMP Importerが出たら、「Import TMP Essentials」→「Import TMP Examples & Extras」をクリック。両方終わったらこのウィンドウは消してOKです。TMP Importerが出なければたぶんそれはそれでOK。

ヒエラルキーを見ると、Canvasの中にButton、その中にText(TMP)ができています。ボタンとテキストの名前をわかりやすいものに変更します。Button→PlayButton、Text(TMP)→PlayButtonTextに変更。

シーンにボタンが表示されていますが、このボタンの中のテキストをPlayに変更したいです(ほんとはさんかくの再生マークにしたいけど画像用意がめんどいので後で)。ヒエラルキーでPlayButtonTextを選択した状態でインスペクターを見ると、TextMeshPro-Text(UI)の中にText Inputがあるので、その中のテキストボックスにPlayと入力。

ボタンのサイズを変更します。ヒエラルキーでPlayButtonを選択。インスペクターのTransformでボタンの配置とサイズを調整します。今回は位置XYZを全て0、幅と高さを両方80に設定しました。


音楽を再生・一時停止するスクリプトを作る
このままではボタンを押してもなんもならん状態なので、ボタンを押したときに音楽を止めたり流したりするスクリプトを書きます。
スクリプトファイルを置く場所は、調べたかんじ、(プロジェクトタブの)Assetsフォルダ内にSprictsフォルダを作成…したほうが多分かっこいいけど、アホは秒で混乱したためとりあえずさっき音源おいたSoundsフォルダ内で作業しました。後から移動しても大丈夫ぽいので、たぶん大丈夫でしょう(希望的観測)。
Soundsフォルダ内の空いている場所を右クリック→作成→MonoBehaviourスクリプトを選択。NewMonoBehaviourScriptというファイルが作られるので、名前を確定せず即座にBgmControllerに書き換えて、エンターキーで確定します。一度名前を確定して後から変更するとバグの原因になるので、確定してしまったらもう一度作成し直したほうがいいらしいです。

作成したファイルを開いて、スプリクトを書きます。今回は以下のようなものを書きました。私はプログラミングわからないので全行説明を書いてます。ごっちゃらしてアレですが、書いた時はどれが何なのか覚えてても数日ほっといたら忘れちゃうので…。書いたら保存します。
using UnityEngine;
using TMPro;
public class BgmController : MonoBehaviour
{
[SerializeField] private AudioSource audioSource; // AudioSourceコンポーネント
[SerializeField] private TextMeshProUGUI playButtonText; // ボタンのテキストオブジェクト
// Start is called once before the first execution of Update after the MonoBehaviour is created
void Start()
{
// AudioSourceコンポーネントを取得
if (!audioSource) audioSource = GetComponent<AudioSource>();
// ボタンのテキストを設定
UpdatePlayButtonText();
}
// 再生/一時停止
public void PauseIfPlayingElsePlay()
{
if (audioSource.isPlaying) // 再生中の場合
{
audioSource.Pause(); // 一時停止
}
else // それ以外の場合
{
audioSource.Play(); // 再生
}
UpdatePlayButtonText(); // ボタンのテキストを設定
}
// ボタンのテキストを設定
private void UpdatePlayButtonText()
{
if (!playButtonText) return; // テキストオブジェクトが設定されていなければ中断
playButtonText.text = audioSource.isPlaying ? "Pause" : "Play"; // 再生中の場合はテキストをPause、再生中でない場合はPlayに設定
}
}
Unityに戻って、BGMインスペクターの一番下にあるコンポーネントを追加から、BgmControllerを検索してクリック。インスペクターにBgmControllerが追加されます。

追加されたBgmControllerの中に、「オーディオソース」と「Play Button Text」があるので、オーディオソースにヒエラルキーのBGMをドラッグ&ドロップ。Play Button Textのほうには、ヒエラルキーのPlayButtonTextをドラッグ&ドロップします。

これでスクリプトの作成は完了。
ボタンクリック時にスクリプトを呼び出せるようにする
ボタンを押したときにさっき書いたスプリクトを呼び出したいので、ボタン側の設定をします。
ヒエラルキーでPlayButtonを選択して、インスペクターの下の方にある「クリック時 ()」の+をクリック。なし (オブジェクト)のところに、ヒエラルキーのBGMをドラッグ&ドロップ。No Functionをクリックして、BgmContlloer→PauseIfPlayingElsePlayを選択。

これでOK。ゲーム再生ボタンをクリックするとゲームが実行され、音楽が流れます。この状態でPlayボタンを押すと、さっき書いたスクリプトのPauseIfPlayingElsePlay関数が呼び出されて再生・一時停止ができます。

ゲームを実行した後は、かならずゲーム停止ボタンを押しておきます。

長いので今回はここまで!
