0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Unity+MIDIで音ゲーを作るならコレ!(2)

Last updated at Posted at 2024-09-07

Unity+MIDIで音ゲーを作るならコレ!(1) の続きです。

MIDIファイルの中身を知る

前回はMIDIファイルをインポートし、再生するところまで行いました。

今回は、曲のリズムに合わせて「何か」をしてみます。

ところで、再生中のConsoleウインドウに大量のメッセージが出ているのに気が付きましたでしょうか?
image.png

MIDIファイルは、mp3のような空気の振動をデータ化したものとは違い、

  • 音を鳴らす
  • 音を止める
  • (音色など)設定を変える

といったデータの集まりでできています。
例えば
Note On ・・・ Note:060 Velocity:075 ・・・
は、「ノートナンバー60を音量75で鳴らす」という情報を含んでいます。

つまり、音が鳴るたびに何らかの命令が出ているので、このタイミングで何かを行うことができれば、曲に合わせて何かを行ったことになります。

スクリプトを作成する

まずはMIDIToObj.csというスクリプトを用意し、中身を下のプログラムに置き換えてください。

MIDIToObj.cs
using MidiPlayerTK;
using System.Collections.Generic;
using UnityEngine;

public class MIDIToObj : MonoBehaviour
{
    // Start is called once before the first execution of Update after the MonoBehaviour is created
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        
    }

    public void OnMidiEvent(List<MPTKEvent> midievents)
    {
        foreach(MPTKEvent ev in midievents)
        {
            string msg = $"cmd:{ev.Command} tr:{ev.Track} ch:{ev.Channel} note:{ev.Value}";
            Debug.LogWarning(msg);
        }
    }
}

次に、Hierarchyウインドウで右クリック>Create Emptyで空のオブジェクトを作成し、わかりやすいように名前をMIDIToObjとします。
さらにこのオブジェクトに、先ほど作成したMIDIToObj.csファイルをドラッグ&ドロップでアタッチします。
image.png

イベントを登録する

「何らかのタイミングで」処理をすることをイベントと呼びます。
先ほど音を再生したMidiFilePlayerにはその機能が備わっています。

MidiFilePlayerのInspectorの真ん中あたりに、ShowUnityEventという項目があるので、左端の▲をクリックして開きます。
image.png

次に、開いた項目の上から2番目(まんなか)の枠の右側にある+ボタンをクリックし、イベントを追加します。
image.png
image.png

None(Object)のところにHierarchyウインドウにあるMIDIToObjをドラッグ&ドロップします。
image.png

さらにNo Functionのリストをクリックし、MIDITOObj > OnMidiEventを選択します。
image.png

image.png

ここまで出来たら再生してみましょう。
image.png

Consoleウインドウに、白い吹きだしのメッセージに交じって黄色い三角のメッセージが出ていると思います。
そこでConsoleウインドウの右上の[ふきだし999+]の部分をクリックすると、三角のメッセージだけが残ります。
image.png

ちなみに、MidiFilePlayer>Log MIDI Events Playedのチェックを外すと白い吹き出しが出なくなります
image.png

よく使われている音を探す

黄色い三角のメッセージの中で、出現頻度が高いものを探してみます。

Consoleウインドウの左から2番目の"Collapse"を押すと同じメッセージがまとまるので、頻出のコマンドがわかりやすくなります。
image.png

出現頻度が高い=その曲でよく使われる音のタイミングで「何か」をすることで、曲に合わせて動いている感じが出やすくなるかと思います。

ちなみに、ch:9は一般的にドラムセットに使われています。
リズムに合わせて何かを行うのであれば、cmd:NoteOn ch:9を探すとよいかと思います。
image.png

曲に合わせてメッセージを出す

先ほどのMIDIToObj.csを書き換えて、曲に合わせてメッセージを出してみます。

MIDIToObj.cs
using MidiPlayerTK;
using MPTK.NAudio.Midi;
using System.Collections.Generic;
using UnityEngine;

public class MIDIToObj : MonoBehaviour
{
    // Start is called once before the first execution of Update after the MonoBehaviour is created
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        
    }

    public void OnMidiEvent(List<MPTKEvent> midievents)
    {
        foreach(MPTKEvent ev in midievents)
        {
            if (ev.Command == MPTKCommand.NoteOn && ev.Channel == 9)
            {
                string msg = $"cmd:{ev.Command} tr:{ev.Track} ch:{ev.Channel} note:{ev.Value}";
                Debug.LogWarning(msg);
            }
        }
    }
}

書き換えたのは

        foreach(MPTKEvent ev in midievents)
        {
+            if (ev.Command == MPTKCommand.NoteOn && ev.Channel == 9)
+            {
                string msg = $"cmd:{ev.Command} tr:{ev.Track} ch:{ev.Channel} note:{ev.Value}";
                Debug.LogWarning(msg);
+            }
        }

の部分です。無数に届くイベントから、cmd:NoteOnかつch:9のときだけメッセージを出すようにしました。

if (ev.Command == MPTKCommand.NoteOn && ev.Channel == 9)
の代わりに、
if (ev.Command == MPTKCommand.NoteOn && ev.Value == 46)
のようにすると、cmd:NoteOnかつnote:46の時だけメッセージが表示されるようになります(Consoleウインドウの左から2番目の"Collaspe"を解除しておかないとメッセージがまとめられてしまいます)。

あとはメッセージの代わりにオブジェクトを出すだけです。ここでは割愛します。

音に合わせて オブジェクトを出すことはできたのですが、
多くの音ゲーは 音が出る以前にすでにオブジェクトが出現しており、
音が出るタイミングでオブジェクトがボーダーラインを超えるといった必要が出てきます。
次回はこちらについて行う予定です。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?