Table of Contents
Unreal Engine でのシリアル通信を可能にするマルチプラットフォーム対応プラグイン。
UniversalSerial には GitHub 版は提供されていません。
概要
UniversalSerial は、Unreal Engine で Arduino やマイコンとのシリアル通信を行うためのプラグインです。
難しいプログラミング知識がなくても、Blueprint(ビジュアルスクリプト)だけでハードウェアとの通信を簡単に実現できます。
IoT プロジェクト、インタラクティブアート、ゲーム内での現実世界との連携など、デジタルと物理世界を繋ぐプロジェクトに最適です。
また、AyumaxSoft が提供する ObjectDeliverer のプロトコルとして使用するための特別な機能も含まれています。
この機能を使用することで、ObjectDeliverer のパケット分割ルールや DeliveryBox の仕組みを活用でき、応用範囲を広げることができます。
対応環境
Windows: Windows 11 24H2 で動作確認済み
Mac: Sequoia 15.5 で動作確認済み
Linux: Ubuntu 24.04 LTS で動作確認済み
プラグインは各OSのAPIを直接使用して機能を実装しています。
そのため、古いオペレーティングシステムでは予期しない動作が発生する可能性があります。 テスターアプリケーションを使用して、事前にお使いの環境で動作するかどうかを確認することをお勧めします。
Unreal Engine 対応バージョン
UniversalSerial のプラグインバージョンごとの対応状況は以下のとおりです。
| プラグインバージョン | 対応UEバージョン |
|---|---|
| v1.3.0 | UE5.5 - 5.8 |
主要な機能
- 利用可能ポートの自動検出
- 検出されたポート名を初期化に直接渡すことが可能
- 通信可能なシリアルポートの自動特定(v1.3.0以降)
- PC に接続されている候補ポートを順に試し、最初に通信可能なポート名を返却
- カスタマイズされた対象ポート設定での初期化
- ポート名
- ボーレート
- データビット
- パリティ
- ストップビット
- フロー制御
- 読み書きタイムアウト
- 受信バッファサイズ
- DTR
- RTS
- 3種類のデータ送受信方法
- バイト配列
- UTF-8 エンコードされた文字列
- バイト配列として送信される16進数 UTF-8 エンコード文字列
- 文字列送受信のための区切り文字設定
- 送信時に区切り文字を自動追加
- 受信時に区切り文字でデータを分離し、文字列を復元
- バックグラウンドスレッドでの受信処理
- ゲームスレッドに重い負荷をかけない
使用例
以下は UniversalSerial を使用するための手順です。
SerialPortManager の作成
まず、SerialPortManager を作成します。今後はこの作成されたオブジェクトを使用して操作を行います。
USerialPortManager* SerialPort = NewObject<USerialPortManager>();
SerialPortManager のイベントを監視
SerialPortManager の必要なイベントを監視します。不要なものはスキップできます。以下の種類のイベントが利用可能です:
- 接続、切断
- データ受信
- バイト配列
- UTF-8 文字列
- 16進数 UTF-8 文字列
- エラー発生

SerialPort->OnConnected.AddDynamic(TestHelper, &USerialPortTestHelper::OnConnected);
SerialPort->OnDisconnected.AddDynamic(TestHelper, &USerialPortTestHelper::OnDisconnected);
SerialPort->OnDataReceived.AddDynamic(TestHelper, &USerialPortTestHelper::OnDataReceived);
SerialPort->OnDataReceivedString.AddDynamic(TestHelper, &USerialPortTestHelper::OnDataReceivedString);
SerialPort->OnDataReceivedHex.AddDynamic(TestHelper, &USerialPortTestHelper::OnDataReceivedHex);
SerialPort->OnError.AddDynamic(TestHelper, &USerialPortTestHelper::OnError);
シリアル通信の開始
シリアルポート情報を設定してから Open を呼び出して通信を開始します。
Initialize に渡す設定は、接続するデバイスまたはソフトウェアの設定と一致している必要があります。
事前に SerialPortManager の GetAvailableSerialPorts を使用して、現在利用可能なシリアルポート名のリストを取得することもできます。

SerialPort->Initialize(
"COM1",
9600,
8,
ESerialPortParity::None,
ESerialPortStopBits::One,
ESerialPortFlowControl::None,
ESerialDataFormat::RawBytes,
true,
true);
通信可能ポートの自動特定(v1.3.0以降)
接続中の候補ポートから「実際に通信できるポート」を自動で探すことができます。
ProbeCommandUTF8で指定した文字列を送り。ExpectedResponseUTF8で指定した文字列が返ってきたポートを通信可能ポートとします。
ProbeCommandUTF8とExpectedResponseUTF8を指定しなかった場合は、最初に開いたポートを返します。

文字列(UTF-8)で特定する
FString PortName = USerialPortManager::FindFirstCommunicableSerialPort(
115200,
8,
ESerialPortParity::None,
ESerialPortStopBits::One,
ESerialPortFlowControl::None,
50,
500,
4096,
true,
true,
TEXT("PING\r\n"),
TEXT("PONG"),
2000);
if (!PortName.IsEmpty())
{
SerialPort->Initialize(
PortName,
115200,
8,
ESerialPortParity::None,
ESerialPortStopBits::One,
ESerialPortFlowControl::None,
ESerialDataFormat::RawBytes,
true,
true);
}
バイナリで特定する
const TArray<uint8> ProbeData = { 0x55, 0xAA };
const TArray<uint8> ExpectedResponse = { 0x5A, 0xA5 };
FString PortName = USerialPortManager::FindFirstCommunicableSerialPortBinary(
115200,
8,
ESerialPortParity::None,
ESerialPortStopBits::One,
ESerialPortFlowControl::None,
50,
500,
4096,
true,
true,
ProbeData,
ExpectedResponse,
2000);
データの送信
データ送信には3つの方法があります。
バイト配列の送信
指定されたバイト配列を送信します。

TArray<uint8> Data = { 0x00, 0x00, 0x00 };
SerialPort->SendData(Data);
UTF-8 文字列の送信
指定された文字列を送信します。AddDelimiter が true に設定されている場合、区切り文字列(デフォルト: \r\n)が文字列の末尾に自動的に追加されます。

FString Data = TEXT("ABC");
SerialPort->SendStringUTF8(Data, true);
16進数 UTF-8 エンコード文字列をバイト配列として送信
指定された16進数文字列をバイト配列に変換してから、バイト配列として送信します。

// 文字列からバイト配列を作成(バイト間のスペースはオプション)
FString Data = TEXT("AA BB CC 01 02 03");
SerialPort->SendStringHex(Data);
データ受信
以下の3つのイベントから受信した値を取得できます。
Initialize または SetDataFormat 時に Data Format で指定した種類の受信イベントのみ、これらのイベントに通知されます。
そのため、常にこれら3つのイベントのうち1つだけがアクティブになります。他の2つは設定されていても通知されません。
通信するデバイスがバイナリデータ(人間の目には意味のないデータ)を送信する場合は、RawBytes を指定して OnDataReceived を使用することをお勧めします。
または、HexString を指定して OnDataReceivedHex を使用すると、バイトデータを文字列形式で取得でき、受信したデータを画面やログファイルに表示したい場合に便利です。
通信するデバイスが文字列を送信する場合は、UTF-8String を指定して OnDataReceivedString イベントを使用してください。

SerialPort->OnDataReceived.AddDynamic(TestHelper, &USerialPortTestHelper::OnDataReceived);
SerialPort->OnDataReceivedString.AddDynamic(TestHelper, &USerialPortTestHelper::OnDataReceivedString);
SerialPort->OnDataReceivedHex.AddDynamic(TestHelper, &USerialPortTestHelper::OnDataReceivedHex);
DTR/RTSの状態変更
実行中にDTR/RTSの状態をそれぞれ切り替えることが可能です。

SerialPort->SetDTR(true);
SerialPort->SetRTS(true);
通信の終了
Close を呼び出して通信を終了します。

SerialPort->Close();
ObjectDeliverer との連携
このページから UniversalSerialOD プラグインをダウンロードしてご利用ください。
Warning
UniversalSerialOD には現在問題が見つかっており、提供を一時中止しております。修正が完了し次第、提供を再開する予定です。
これは現在無料で提供されています。他のプラグインと連携するプラグインは Fab の規約に違反し、そこで公開できないため、このサイトでのダウンロード提供のみとなっています。
このプラグインを使用することで、UniversalSerial を ObjectDeliverer のプロトコルとして使用できるようになります。
この連携機能を使用するには、以下の3つのプラグインをインストールする必要があります:
- ObjectDeliverer
- UniversalSerial
- UniversalSerialOD
この連携機能により、プロジェクトに以下の利点が提供されます:
- シリアル通信において、ObjectDeliverer のパケット分割ルールや DeliveryBox の仕組みを使用できる
- デバイスとの通信機能を作成する際、デバイスがない場合は TCP/IP や他のプロトコルを使ってモックを作成し、通信方法を切り替えて開発を進めることができる
使用するには、ObjectDelivererManager の Start メソッドに「Create Protocol Serial Port」を挿入するだけです。
その後、ObjectDeliverer の機能を使用してシリアル通信の送受信を行うことができます。

UniversalSerialOD プラグインの Content フォルダにある UniversalODSerialUMG アセットを参照してください。このプラグインの実装例が含まれています。

プラグイン購入前の事前検証

UniversalSerial は OS の API を直接使用しています。そのため、環境によっては正常に動作しない場合があります。
このページからテスターアプリをダウンロードでき、購入前にシリアル通信が可能かどうかを確認することをお勧めします。
このテスターアプリは UniversalSerial プラグインを使用してシリアル通信を行います。そのため、このアプリで通信が動作すれば、プラグインを使用した通信も動作する可能性が高いです。
また、このアプリの Blueprint 実装はプラグインに含まれているため、購入後のプラグインの使用方法を学ぶ際にも役立ちます。
FAQ
よくある質問はこちらで確認できます。
レビューをお寄せください
このプラグインをご利用いただきありがとうございます。Epic Games Fabストアでのレビューは、今後の開発の大きな励みになります。ぜひご感想をお聞かせください!
Fabストアでレビューを書く