先月に引き続きVRドラムシュミレーターを作成。
前回の記事はこちら。
今回はバスドラム音を鳴らしたく、実際にペダル操作をして音がなるようにする。
ペダルはヤマハのフットスイッチにてシュミレートすることに決めた。
もともとは電子ピアノ用であるが、フットスイッチが踏まれているかいないかの2値の制御が可能なため代用が可能である。
フットスイッチが踏まれていないとクローズ状態、踏まれるとオープン状態になる。
これを2台接続し、Arduionoで電気的に接続されているか確認⇒シリアル通信にてUnityとやりとりすることで
VR上でバスドラムのシュミレートが可能にする。
スイッチ箇所にフットペダルを接続し、Arduinoのプルアップ抵抗を利用する。
// variables will change: int footState = 0; void setup() { pinMode(5, INPUT_PULLUP); pinMode(10, INPUT_PULLUP); Serial.begin(115200); // ハードウェアシリアルを準備 while (!Serial) { ; // シリアルポートの準備ができるのを待つ(Leonardoのみ必要) } } void loop() { // read the state of the pushbutton value: footState = digitalRead(leftFootSW); footState += digitalRead(rightFootSW) << 1; Serial.print(footState); Serial.print("\n"); delay(50); }
footStateで現在のフットスイッチの状態を保持。
状態は下記の通り。
値 | 左フットスイッチ | 右フットスイッチ |
0 | オープン | オープン |
1 | クローズ | オープン |
2 | オープン | クローズ |
3 | クローズ | クローズ |
区切り文字として改行コードを挿入する。
Unityでのシリアル通信は様々なページで紹介されている。
using UnityEngine; using System.Collections; using System.IO.Ports; using System.Threading; public class SerialHandler : MonoBehaviour { public delegate void SerialDataReceivedEventHandler(string message); public event SerialDataReceivedEventHandler OnDataReceived = delegate { }; public string portName = "COM1"; //各自のマイコンのCOMポート public int baudRate = 115200; private SerialPort serialPort_; private Thread thread_; private bool isRunning_ = false; private string message_; private bool isNewMessageReceived_ = false; void Awake() { Open(); } void Update() { if (isNewMessageReceived_) { OnDataReceived(message_); isNewMessageReceived_ = false; } } void OnDestroy() { Close(); } private void Open() { serialPort_ = new SerialPort(portName, baudRate, Parity.None, 8, StopBits.One); serialPort_.ReadTimeout = 20; serialPort_.Open(); serialPort_.NewLine = "\n"; isRunning_ = true; thread_ = new Thread(Read); thread_.Start(); } private void Close() { isRunning_ = false; if (thread_ != null && thread_.IsAlive) { thread_.Join(); } if (serialPort_ != null && serialPort_.IsOpen) { serialPort_.Close(); serialPort_.Dispose(); } } private void Read() { while (isRunning_ && serialPort_ != null && serialPort_.IsOpen) { try { message_ = serialPort_.ReadLine(); isNewMessageReceived_ = true; } catch (System.Exception e) { } } } public void Write(string message) { } }
上記は最低限のシリアル通信ができるプログラムである。
Open()にてシリアル通信を開始し、Read()で受信したデータを受け取り、
区切り文字まで受信したらデリゲートで登録したメソッドを呼び出す。
using System.Collections; using System.Collections.Generic; using UnityEngine; public class DoSomething : MonoBehaviour { public SerialHandler serialHandler; void Start() { //信号を受信したときに、そのメッセージの処理を行う serialHandler.OnDataReceived += OnDataReceived; } void Update() { } //受信した信号(message)に対する処理 void OnDataReceived(string message) { var data = message.Split( new string[] { "\n" }, System.StringSplitOptions.None); Debug.Log(data[0]); } }
Start()にてSerialHandlerのデリゲートに自メソッドのOnDataReceived()を登録。
メッセージを受信するとOnDataReceived()に受け取ったメッセージが返されるので、
この中で音声をならす処理を実装する。
前回と同様にAudio Sourceを呼ぶことでバスドラムの音を鳴らすことができた。
VRドラムシュミレーターを一通り完成させ、
余力があれば、録音機能などを実装する。