前回の記事では、シリアル通信のためのPluginを作ることで、Arduino⇔Unityのシリアル通信を実現しました。
今回はUniRxを使うことで、前回よりも簡単にArduinoとシリアル通信をする方法を紹介します。今回の記事の内容は次のとおりです。
UniRxとは
UniRxとはUnity Reactive Extensionsの略で、名前の通り(?)Unityで非同期通信をしたいときに使うと便利なツールになります。UniRxはAsset Storeから無料で手に入れることができます。
今回の記事では、UniRxはスレッドを作るためだけに使います(贅沢)UniRxの詳しい説明はしませんが、非常に便利なライブラリなのでいつか解説を書く・・・かも。
Arduino側のプログラムを作る
こちらはシリアル通信でデータを一方的に送りつけるだけのプログラムです。次のプログラムをスケッチに書いて下さい。
byte a = 0; void setup() { Serial.begin(9600); } void loop() { a++; Serial.println(a); }
プログラムの内容は・・・setupメソッドの中でシリアル通信を開始しています。loopメソッドの中では、変数aの値をインクリメントしながらシリアルにどんどん流し込んでいるだけのプログラムになります。
プログラムができたら、書き込みボタンでArduinoに書き込んでおきましょう。
Unity側のプログラムを作る
続いてUnity側のシリアル通信プログラムを作ります。こちらはシリアル通信で送られてくるデータを受け取るプログラムです。
UniRxを使うため、Asset Storeからダウンロードしてインポートしておいてください。
また、Unityでは標準で.NET 2.0のサブセットを使うように設定されていますが、サブセットにはSerialクラスが含まれていないため、.NET 2.0 Subsetから.NET 2.0に変更する必要があります。
メニューバーからEdit -> Project Settings -> Player
を選択し、API Compatibility Levelを.NET 2.0に変更してください。
続いて、シリアル通信用のスクリプトを作成します。プロジェクトビューで右クリックし、「Create」→「Script」→「C# Script」を選択し、SerialController.csという名前で保存し、作成したファイルに次のスクリプトを入力してください。
using System.Collections; using System.Collections.Generic; using System.Threading; using System; using System.IO.Ports; using UnityEngine; using UniRx; public class Serial : MonoBehaviour { public string portName; public int baurate; SerialPort serial; bool isLoop = true; void Start () { this.serial = new SerialPort (portName, baurate, Parity.None, 8, StopBits.One); try { this.serial.Open(); Scheduler.ThreadPool.Schedule (() => ReadData ()).AddTo(this); } catch(Exception e) { Debug.Log ("can not open serial port"); } } public void ReadData() { while (this.isLoop) { string message = this.serial.ReadLine(); Debug.Log( message ); } } void OnDestroy() { this.isLoop = false; this.serial.Close (); } }
ここでは、UniRxを使うため、using UniRX;
を追加しています。Startメソッドの中でSerialクラスのインスタンスを作成した後、Scheduleメソッドを使ってReadDataスレッドを立ちあげています。
ReadDataメソッドの中ではSerialクラスのReadLineメソッドを使って、シリアルで送られてくるデータを読んで表示しています。
ゲームを終了する場合はOnDestroyメソッドが実行されます。その中で、スレッドを抜けて、シリアルポートを閉じています。
実行してみる
スクリプトが作成できたら、空のゲームオブジェクトを作って、それにスクリプトをアタッチしておきましょう。アタッチしたゲームオブジェクトのインスペクタから、ボーレートとポート名を設定してください。ボーレートはArduino側で指定した9600に設定します。
ポート名はArduinoを起動し、メニューバーからツール -> ポート
で確認することができます。
これで準備完了です。ArduinoをPCに接続し、Unityを実行してみてください。コンソールビューの数字が増加して1〜255を繰り返せば成功です。
まとめ
Unityで非同期通信やスレッドなどを使いたい場合はUniRxを使うことで、非常にスッキリとしたプログラムを書くことができます。