DJコントローラーで動作する何かしらをUnityで作ろう!~初歩編~

この記事は TUT Advent Calendar 2022 9日目の記事です。

はじめに

初めましての方は初めまして、そうではない方はこんにちは。北海道 函館高専出身で現在はTUT B3 3系所属のさわでぃーです。最近は寒さに磨きがかかってきたことも相まって体調を崩さないかハラハラしながら生活しています。*1

Advent Calendarということで(稚拙ながら)技術的なことを書いてみようと模索した結果、所有物で面白そうなことが出来そうな機材があったのでそちらを使用してちょっとした実装を行ってみようと思います。本当に面白いのかはさておきですが。

ちなみに当方初ブログ執筆です。お手柔らかにお願いします。

使用機材

  • DDJ-FLX6

www.pioneerdj.com所謂DJコントローラー、このモデルはPCと接続して動作させるタイプとなってます。私は自身の所属する総合文化部 音楽技術部門(通称: テクノ部, TechnoTUT)というサークルで初心者ながらのDJ活動*2を行っており自前の物を所持していた訳ですが、実は後述の通りDJ用途以外にも使用することが出来たりします。今回のメイン機材。

  • PC

DJコントローラーを接続して動作させるために必要となります。ある程度の性能*3を有していればデスクトップでもラップトップでもなんでも良いと思われます(てきとう)。

DJ用途以外の使用方法って?

DJコントローラーをただPCに接続しただけではDJは出来ません、専用のソフトウェアを介する必要があります。逆に言ってしまえば、専用のソフトウェアを介していない時のDJコントローラーは"何かしらの"信号を出力出来るだけの状態となっているという事です。では一体どんな信号送れるの?という話になるのですが、ここは大人しく公式より公表されている仕様諸々を見ることにしましょう。今回使用するDJコントローラーの販売元である Pioneer DJのサポートページからDDJ-FLX6のページを辿っていくとDDJ-FLX6 MIDI-Compatible Softwareという項目が。このページを見るに、どうやらDJコントローラーには任意の対応ソフトウェアにMIDIメッセージを割り当てることが出来るらしいですね。実際にコントローラーから出力されるMIDIメッセージ一覧も同ページにて公開されています。

https://www.pioneerdj.com/-/media/pioneerdj/software-info/controller/ddj-flx6/ddj-flx6_midi_message_list_j1.pdf

以上から 何かしらの信号=MIDIメッセージ が出力されることが分かりました。今回はこのMIDIメッセージの割り当てが可能な性質を利用していこうといった記事です。

何を作ろうか

完全見切り発車が故に初手のここで万策尽きました、ありがとうございます。と言って投げ出すのはお門違いな気しかしないので、せめてもの成果物を錬成していきます。

個人的な意見ですが、DJコントローラーで何よりも目立つ箇所といえば両サイドの円盤パーツであるジョグホイールだと思っています。せっかくならそこで大々的に操作出来る要素があると良いかも…。などと色々ごちゃごちゃ考えた結果、ひとまずその箇所に動作を割り当ててみることにしました(雑!)。同時に昔軽く使ったゲームエンジン Unity の復習もしたかったので、それも兼ねて今回はDJコントローラーからの入力でスクリプトを介してUnity上でオブジェクトを動かしてみようという方針で進めていこうと思います。

使用ソフトウェア

前述の通り Unity( Version: 2021.3.14f1 ) を使用します。それに伴い言語はC#

ちなみに初期状態だとUnityではMIDI入力には対応していません。今回は有志の方が作成したプラグインである MidiJack を使用してMIDI入力を受け取ります。

github.com上記プラグインの導入後、Unity上でMIDIの入力信号を確認出来るようになります。

wheelSignal

右ホイール操作時のMIDI信号表示

MIDIメッセージが表示されているので、信号を受け取れていることが分かります。ここでMIDIメッセージ一覧より右ホイール操作時(今回はJOG DIAL R (Platter))のMIDI-INを参照すると、Status: 0xB1 / Data1: 0x22が送信されることが分かります。ホイールを時計方向に操作したときの基準値である0x41と併せて表示されていることからも、MidiJackによる信号の受け取りは正常なことが確認出来ました。

成果物

2Dプロジェクトを作成し、シーンの中央に正方形を配置します(下図参照)。この正方形をスクリプトによって動作させていきます。

ObjectImage

オブジェクト配置画面

2Dプロジェクトなのでオブジェクトの動作は上下左右の4方向とします。考えた結果、右ホイールには上下移動を、左ホイールには左右移動をそれぞれ回転方向によって場合分けすることで実装することとしました。ホイールの左右については完全に気まぐれ決定で、移動方向については回転方向から自然な流れになるような感じで行きます。

今回のホイールによるオブジェクト動作スクリプトを作成する上で必要となる情報は以下の通りです。

  • ホイールのMIDI信号が送信されるチャンネル
  • ホイールの回転方向(時計回り/反時計回り)の切り替わる値
  • ホイールに触れているかどうかの判定値

プラグインの配布元にあったテスト用スクリプトMIDIメッセージ一覧とにらめっこして、今回の場合では次のようなパラメータとしてスクリプトの記述を行います。

  • 左ホイールのMIDIチャンネル: CH1、右ホイールのMIDIチャンネル: CH2
  • 回転方向: 0.5基準と判断(時計回り0.5~ , 反回転~0.5だったため)
  • 接触判定: 0(非接触) or 1(接触

という訳で出来上がったスクリプトがこちらです!(3分クッキング)

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using MidiJack;

public class SquareController : MonoBehaviour
{

    MidiChannel channel;    // MidiChannel(Ch1-Ch16)
    int note, knob;         // note(Midi-Note), knob(Midi-CC)
    float velosity, value;  //velosity(0 or 1), value(0 to 1)

    private Vector2 squarePos; // (x, y)
    // Start is called before the first frame update
    void Start()
    {
        squarePos = new Vector2(0, 0);
    }

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

        Transform squareTransform = this.transform;
        squarePos = squareTransform.position;

        switch ( channel )
        {
            // Ch1: Controller-wheelLeft
            case MidiChannel.Ch1:
                // velosity != 0: touch-Wheel
                // value < 0.5: counterclockwise rotation,
                // value > 0.5: clockwise rotation
                if( velosity != 0 && value < 0.5 ){
                    Debug.Log("action-moveUp");
                    squarePos.y += 0.01f;
                    squareTransform.position = squarePos;
                }else if( velosity != 0 && value > 0.5 ){
                    Debug.Log("action-moveDown");
                    squarePos.y -= 0.01f;
                    squareTransform.position = squarePos;
                }else{
                    Debug.Log("else in");
                }
                break;
            // Ch2: Controller-wheelRight
            case MidiChannel.Ch2:
                if( velosity != 0 && value < 0.5 ){
                    Debug.Log("action-moveRight");
                    squarePos.x += 0.01f;
                    squareTransform.position = squarePos;
                }else if( velosity != 0 && value > 0.5 ){
                    Debug.Log("action-moveLeft");
                    squarePos.x -= 0.01f;
                    squareTransform.position = squarePos;
                }else{
                    Debug.Log("else in");
                }
                break;
            default:
                Debug.Log("action-(Default)");
                break;
        }
    }

    // call-fanction Initialize (Object-active)
    private void OnEnable() {
        MidiMaster.noteOnDelegate += NoteOn;
        MidiMaster.knobDelegate += KnobOn;
    }

    // call-fanction Clear (Object-inactive)
    private void OnDisable() {
        MidiMaster.noteOnDelegate -= NoteOn;
        MidiMaster.knobDelegate -= KnobOn;
    }

    // setter-function
    private void NoteOn(MidiChannel channel, int note, float velosity) {
        // set-(channel, note, velosity)
        this.channel = channel;
        this.note = note;
        this.velosity = velosity;
        Debug.Log("Set( NoteOn ): " + channel + ", " + note + ", " + velosity);
    }

    private void KnobOn(MidiChannel channel, int knob, float value) {
        // set-(channel, knob, value)
        this.channel = channel;
        this.knob = knob;
        this.value = value;
        Debug.Log("Set( KnobOn ): " + channel + ", " + knob + ", " + value);
    }
}

※あんまり記述慣れしてないので粗雑なコードです、お許しください。

完成したスクリプトを正方形オブジェに割り当てて動かすと次のようになります。

ホイールの挙動に合わせ、上下左右に動いているので成功です。

まとめ

  • ひとまずホイールに操作を割り当ててみましたが、他の箇所が何もないのとパラメータ類がガバガバなので時間を見つけてなんとかしたいと思ったりしています。これで操作して遊べるゲームとか作れると面白そうかも。実用性があるかまではちょっと…。
  • 慣れない事をそれでもやろうとする時は時間に余裕を持って作業しましょう。ぎりぎりにやると時間による焦りが発生する可能性が高いです(自戒①)。
  • 機材は本来の用途でもしっかりと利用すべきです。私は最近まであまり使ってませんでした(自戒②)。

(おまけ)宣伝的な

  • テクノ部人員募集中です。DJに興味ある!といった方はもちろん、音楽を作ってみたい方(DTM)、イベント時に演出で使えそうな物を工作したり広告のデザインやイラストの制作をしてみたい方、あるいはそれらが得意 / 経験有り な方々が増えて欲しいと思ってます。何より音楽が好きなら入って後悔することはないサークルだと思っているので、少しでも気になった方は是非、クラブハウス2階の総合文化部部室まで!*4

    twitter.com

  • 私事ですが人と外食に行ったりするのが大好きです。美味しい物食べに行くときとか飲みやるときは誘ってください(受け身)

 

*1:自分は北海道出身ですが、豊橋もこの時期普通に寒いと思います。風がやばい。

*2:Q: DJって何やるんですか? A: 雰囲気で曲繋いでます

*3:実装にUnityを利用するので、プログラム書いてUnity上で動作させる程度の性能は必要です。

*4:先日部室の機材が新調されました。デカい機材でDJやるの楽しい