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)があらかじめコード化されています。

UnityでC#スクリプトの生成

C#スクリプト「SerialHandler.cs」を次に示します。COMポート番号は「COM2」で9600BPSにしました。使用したイベントを次に示します。

使用したUnityのイベント
イベント名 説明
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の使用には制限(使用できない?)があります。

SerialPort クラスの使用設定

C#スクリプトをオブジェクトに登録

Assetsの置かれた作成したC#スクリプト「SerialHandler.cs」を、Hierarchyに置かれたオブジェクト「Cube」にドラッグ&ドロップして、オブジェクト「Cube」に作成したC#スクリプトを登録します。Cubeをクリックすると、Inspectorに次のように表示されます。

C#スクリプトをオブジェクトに登録

COMポートから慣性データの入力

LSM303DLHを用いたPro Microのデジタルコンパス・加速度入力 プログラム」で作成したPro Microをパソコンに接続して、デジタルコンパス・加速度のデータをUnityに取り込みます。

Unityは二けたのCOMポート番号を持つCOMポートからデータを受け取ることができないため、次のエラーメッセージがConsoleに表示されます。

Unity COMポート番号「14」

このため、デバイスマネージャで対応するポートのデバイスのプロパティを選択して、次の方法を使用して、空いている一桁のCOMポート番号に変更する必要があります。

COMポート番号の割り当て

設定が終わったところでPlayボタンを押すと、次のようにConsoleに表示されます。「Serial-Update」と「OnDataReceived1」のカウンタが更新されているので、別スレッドで実行されていることがわかります。

UnityでC#スクリプトの実行

C#スクリクトを変更して、入力したデータを表示させてみると次のように表示されます。「LSM303DLHを用いたPro Microのデジタルコンパス・加速度入力 プログラム」での結果と同等の内容が表示されます。

Unityで受信したデジタルコンパス・加速度データ