Unity(Ver4.5)でC#スクリプトを用いて、COMポートからデータを入力します。
プロジェクトとオブジェクトの作成
メインメニューから、「File」→「New Project」を選択して新規プロジェクトを作成します。その後、HierarchyViewのCreateタブをクリックし、Cubeを選択して、Cubeのオブジェクトを作成し、Sceneで確認しやすいように、HierarchyViewから今度はDirectional lightを選択してライティングします。
シリアル転送スクリプトの作成
シリアル転送のC#スクリプトを作成します。次のようにProjectタブのCreateプルダウンよりC#Scriptを選択すると、Unityで使用できるC#スクリプトのテンプレートがAssetsに生成されます。このテンプレートには、UnityEngineを呼び出し、MonoBehaviourを基底クラスとし、各イベント(StartやUpdate)があらかじめコード化されています。
C#スクリプト「SerialHandler.cs」を次に示します。COMポート番号は「COM2」で9600BPSにしました。使用したイベントを次に示します。
イベント名 | 説明 |
---|---|
Start | スクリプトのインスタンスが有効になると、最初のフレームのアップデート前に Start が呼び出されます。 |
Upadate | フレームごとに一度呼び出されます。これは、フレームのアップデートのメインとなる関数です。 |
OnDestroy | オブジェクトが破棄される直前のフレーム更新後に OnDestroy が呼び出されます。(オブジェクトは Object.Destroy あるいはシーン終了時に破棄されます) |
Startイベント時に、シリアルポートをOpenし、読み込みメソッド「Read」を別スレッドで起動します。Upadateイベント時に、シリアルポートからデータが受信されているかを確認し、受信されていれば、OnDataReceivedメソッドを呼び出し、受信したデータを分割します。ここでセンサ情報を編集できます。OnDestroyイベントは、ゲームの実行が終了すると発生します。ここでは、シリアルポートのClose処理と、別スレッドの破棄を行います。「Debug.LogWarning」は、実行のトレースを行うために使用します。ここで指定した文字列がConsoleに表示されます。
SerialHandler.cs
using UnityEngine; using System.Collections; using System.IO.Ports; using System.Threading; public class SerialHandler : MonoBehaviour { public string portName = "COM2"; public int baudRate = 9600; private SerialPort serialPort_; private Thread thread_; private bool isRunning_ = false; private string message_; private bool isNewMessageReceived_ = false; void Start() { Debug.LogWarning("Start"); Open(); } void Update() { Debug.LogWarning("Serial-Update"); if (isNewMessageReceived_) { OnDataReceived(message_); } } void OnDestroy() { Debug.LogWarning("OnDestroy"); Close(); } private void Open() { serialPort_ = new SerialPort(portName, baudRate, Parity.None, 8, StopBits.One); serialPort_.Open(); isRunning_ = true; thread_ = new Thread(Read); thread_.Start(); } private void Read() { Debug.LogWarning("Read1"); while (isRunning_ && serialPort_ != null && serialPort_.IsOpen) { Debug.LogWarning("Read2"); try { message_ = serialPort_.ReadLine(); // Debug.LogWarning(message_); isNewMessageReceived_ = true; } catch (System.Exception e) { Debug.LogWarning(e.Message); } } } private void Close() { isRunning_ = false; if (thread_ != null && thread_.IsAlive) { thread_.Join(); } if (serialPort_ != null && serialPort_.IsOpen) { serialPort_.Close(); serialPort_.Dispose(); } } void OnDataReceived(string message) { Debug.LogWarning("OnDataReceived1"); var data = message.Split( new string[] { "\t" }, System.StringSplitOptions.None); if (data.Length < 2) return; try { } catch (System.Exception e) { Debug.LogWarning(e.Message); } } }
C#スクリプトの編集にはVisual Studio Express 2013を使用しました。UnityのエディタからVisual Studioに変更する方法は、「UnityのエディタをVisual Studio Express 2012に変更する」を参照してください。
SerialPort クラスの使用設定
メインメニューから「Edit」→「Project Settings」→「Player」を選択し、次のようにInspectorタブの API Compatibility Level を .NET 2.0 Subset から .NET 2.0 へと変更すると、System.IO.Ports.SerialPort クラスが扱えるようになります。ただし、delegateやSerialDataReceivedEventHandlerの使用には制限(使用できない?)があります。
C#スクリプトをオブジェクトに登録
Assetsの置かれた作成したC#スクリプト「SerialHandler.cs」を、Hierarchyに置かれたオブジェクト「Cube」にドラッグ&ドロップして、オブジェクト「Cube」に作成したC#スクリプトを登録します。Cubeをクリックすると、Inspectorに次のように表示されます。
COMポートから慣性データの入力
「LSM303DLHを用いたPro Microのデジタルコンパス・加速度入力 プログラム」で作成したPro Microをパソコンに接続して、デジタルコンパス・加速度のデータをUnityに取り込みます。
Unityは二けたのCOMポート番号を持つCOMポートからデータを受け取ることができないため、次のエラーメッセージがConsoleに表示されます。
このため、デバイスマネージャで対応するポートのデバイスのプロパティを選択して、次の方法を使用して、空いている一桁のCOMポート番号に変更する必要があります。
設定が終わったところでPlayボタンを押すと、次のようにConsoleに表示されます。「Serial-Update」と「OnDataReceived1」のカウンタが更新されているので、別スレッドで実行されていることがわかります。
C#スクリクトを変更して、入力したデータを表示させてみると次のように表示されます。「LSM303DLHを用いたPro Microのデジタルコンパス・加速度入力 プログラム」での結果と同等の内容が表示されます。