先月に引き続き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ドラムシュミレーターを一通り完成させ、
余力があれば、録音機能などを実装する。