ObjectDeliverer

Table of Contents

TCP/IP、UDP、共有メモリ、ファイルベース通信など、様々な通信方法を簡単に切り替えられるライブラリ。

概要

ObjectDeliverer は Unreal Engine プロジェクトでのデータ通信を簡素化するために設計された柔軟なライブラリです。

TCP/IP、UDP、WebSocket, 共有メモリ、ファイル転送などの様々な通信プロトコルを簡単に切り替えることができ、C++ と Blueprint の両方で利用できます。

このプラグインの最大の特徴は、通信方法を切り替える際にコードをほとんど変更する必要がないことです。プロトコルを変更するだけで、他のコードはそのまま使えます。

これにより、例えば TCP/IP で実装した通信を UDP に切り替えることが簡単になります。これは特にプロトタイプ段階のプロジェクトで、様々な通信方法を試したい場合に便利です。

Epic Games公式スポットライトで紹介されました

ObjectDelivererプラグインがEpic Gamesの公式スポットライト記事で紹介されました。

自動運転車両テスト用シミュレーターにてシームレスな通信の実現に重要な役割を果たしています。

シミュレーターの開発における次の段階では、Unreal Engine と物理的な自動車の間で双方向に情報を送る方法を考案する必要がありました。そのために、Espineira 氏は ObjectDeliverer プラグインを使用しました。これによってサーバーへとつながるブループリントが提供され、データの送受信が可能になります。

Epic Games スポットライト : 自動運転車のテスト用のハイブリッド リアルタイム シミュレーター

主要な機能

  • 様々な通信プロトコルのサポート(TCP/IP、UDP、WebSocket, 共有メモリ、ファイルなど)
  • プロトコル間の簡単な切り替え
  • C++ と Blueprint の両方に完全対応
  • 非同期通信(メインスレッドをブロックしない通信)
  • 柔軟なデータフォーマットサポート(バイナリ、プレーンテキスト、JSON テキスト)

Unreal Engine 対応バージョン

ObjectDeliverer のプラグインバージョンごとの対応状況は以下のとおりです。

プラグインバージョン対応UEバージョン
v1.9.0UE5.5 - 5.8
v1.8.0UE5.4 - 5.7
v1.7.0UE5.4 - 5.6
v1.6.1UE5.4 - 5.6

対応プラットフォーム

区分プラットフォーム
ターゲットプラットフォームWindows, Mac, Linux, iOS, Android
開発プラットフォームWindows, Mac, Linux

使用例

以下は ObjectDeliverer を使用して TCP サーバーを作成する基本的な実装例です。

Blueprint

C++

void UMyClass::Start()
{
    auto deliverer = UObjectDelivererManager::CreateObjectDelivererManager();

    // イベントハンドラーを設定
    deliverer->Connected.AddDynamic(this, &UMyClass::OnConnect);
    deliverer->Disconnected.AddDynamic(this, &UMyClass::OnDisConnect);
    deliverer->ReceiveData.AddDynamic(this, &UMyClass::OnReceive);

    // 通信を開始
    // プロトコル: TCP/IP サーバー
    // データ分割ルール: ヘッダー(サイズ) + ボディ
    // シリアライゼーション方法: バイト配列
    deliverer->Start(UProtocolFactory::CreateProtocolTcpIpServer(9099),
                     UPacketRuleFactory::CreatePacketRuleSizeBody());
}

void UMyClass::OnConnect(UObjectDelivererProtocol* ClientSocket)
{
    // データを送信
    TArray<uint8> buffer;
    deliverer->Send(buffer);
}

void UMyClass::OnDisConnect(UObjectDelivererProtocol* ClientSocket)
{
    // 切断を処理
    UE_LOG(LogTemp, Log, TEXT("closed"));
}

void UMyClass::OnReceive(UObjectDelivererProtocol* ClientSocket, const TArray<uint8>& Buffer)
{
    // 受信したデータを処理
}

プロトコルの切り替え

プロトコルを変更するには、Start メソッドに異なるプロトコルを渡すだけです。上記の例に以下の変更を加えることで、UDP 送信プロトコルに切り替えることができます。

Blueprint

C++

// UDP 送信者
deliverer->Start(UProtocolFactory::CreateProtocolUdpSocketSender("192.168.0.100", 9099),
UPacketRuleFactory::CreatePacketRuleSizeBody());

ObjectDeliverer は以下のプロトコルをサポートしています。独自のカスタムプロトコルを作成することも可能です。

  • TCP/IP サーバー
  • TCP/IP クライアント
  • TCP/IP TLS サーバー (v1.9.0以降)
  • TCP/IP TLS クライアント (v1.9.0以降)
  • UDP 送信者
  • UDP 受信者
  • WebSocket クライアント
  • 共有メモリ(Windows のみ)
  • ファイル書き込み
  • ファイル読み込み
  • リフレクション

TCP/IP サーバー、クライアント

TCP/IP 通信用のプロトコルです。TCP/IP は一対多通信をサポートしているため、単一のサーバーに複数のクライアントが接続できます。

また、パケット再送機能を備えているため、送信されたメッセージは確実に受信者に届けられます。

ただし複数のパケットを送った際に、複数回分のパケットが結合して届いたり、1回分のメッセージの途中で分断されて相手に届くことがあります。そのためパケット分割ルールのNodivision以外を使うことをお勧めします。

Create Protocol Tcp Ip Server

パラメータ説明
Portサーバーが通信を待ち受けるポート

Create Protocol Tcp Ip Client

パラメータ説明
IpAddressサーバーが待ち受けているIPアドレス
Portサーバーが待ち受けているポート
RetryConnectに失敗した場合に自動でリトライする
Auto Connect After Disconnect接続が切れた場合に自動で再接続を試みる

TCP/IPの特徴

項目説明
再送機能あり
常時接続あり
相性の良い分割ルールFixedLength, Terminate, SizeBody (Nodivisionは向いていない)
信頼性高い
注意点パケットが結合したり分断して相手に届く場合がある

TCP/IP TLS サーバー、クライアント (v1.9.0以降で利用可能)

TCP/IP に TLS を追加した暗号化通信プロトコルです。TCP/IP と同様に一対多通信(サーバーに複数クライアント接続)が可能で、通信内容の暗号化と証明書ベースの認証に対応します。

用途に応じて、自己署名証明書 + 公開鍵ピンニング、カスタムCA証明書、双方向TLS(mTLS) などの構成を選べます。

Create Protocol Tcp Ip Server Tls

パラメータ説明
Portサーバーが通信を待ち受けるポート
CertPathサーバー証明書ファイルのパス
KeyPathサーバー秘密鍵ファイルのパス
Minimum ProtocolTLSの最小バージョン(指定以上を許可)

Create Protocol Tcp Ip Client Tls

パラメータ説明
IpAddressサーバーが待ち受けているホスト名またはIPアドレス
Portサーバーが待ち受けているポート
RetryConnectに失敗した場合に自動でリトライする
Auto Connect After Disconnect接続が切れた場合に自動で再接続を試みる
Minimum ProtocolTLSの最小バージョン(指定以上を許可)

TCP/IP TLSの特徴

項目説明
再送機能あり
常時接続あり
相性の良い分割ルールFixedLength, Terminate, SizeBody (Nodivisionは向いていない)
信頼性高い
注意点証明書の設定(CA/自己署名/ピンニング/mTLS)により必要オプションが変わる

TLS のオプション選定(どのユースケースで何を有効化するか)はこちらにまとめています。

ObjectDeliverer の TLSClient と通信可能な TLSServer のサンプルを GitHub で公開しているので、参考にできます。

レポジトリ: AyumaxSoft/TLSServerSample

OpenSSL コマンドで証明書を手動作成する手順はこちらです。

UDP 送信者、受信者

UDP 通信用のプロトコルです。TCP/IP とは異なり、UDP 通信は接続ステップなしに受信者にメッセージを一方的に送信します。

パケット再送機能がないため、ネットワーク状況によってはパケットが届かない場合があります。しかし、それによって TCP/IP よりも優れたパフォーマンスを提供します。

毎Tick状態を送信する機能など、まれにパケットが届かないことが起きても大丈夫な場合に適したプロトコルです。

Create Protocol Udp Socket Sender

パラメータ説明
IpAddress送信先のIPアドレス
Port送信先のポート番号

Create Protocol Udp Socket Sender with Broadcast

パラメータ説明
IpAddress送信先のIPアドレス
Port送信先のポート番号
Enable Broadcastブロードキャスト送信を有効にする

Create Protocol Udp Socket Receiver

パラメータ説明
Bound Port受信を待ち受けるポート番号

UDPの特徴

項目説明
再送機能なし
常時接続なし
相性の良い分割ルールNodivision (その他のルールを使ってもOK)
注意点パケットがロストする場合がある

WebSocket クライアント (v1.7.0以降で利用可能)

WebSocketのクライアントです。

現在多くのWebシステムで採用されているWebSocketのサーバーと接続することができます。

wssのURLを使用して暗号化通信も可能です。

Create Protocol Web Socket Client

パラメータ説明
UrlWebSocketサーバーのURL (例: ws://localhost:8080)

Create Protocol Web Socket Client with Protocols

パラメータ説明
UrlWebSocketサーバーのURL
Protocolsサブプロトコルのリスト

Create Protocol Web Socket Client with Headers

パラメータ説明
UrlWebSocketサーバーのURL
Protocolsサブプロトコルのリスト
Headersカスタムヘッダーのリスト

WebSocketの特徴

項目説明
再送機能あり
常時接続あり
相性の良い分割ルールNodivision (その他のルールを使ってもOK)

共有メモリ

共有メモリは、複数のアプリケーションで共有できるメモリ空間を作成し、この空間にメッセージの書き込みと読み込みを行えます。

ネットワーク通信ではないため、同じ PC 上でのみ値の送受信が可能です。

また、データが送信された(書き込まれた)ことを受信者が知る方法がないため、受信側は定期的にメモリを読み込んで新しい書き込みがないかチェックする必要があります。ObjectDeliverer はこの処理を自動的に行うため、通常ユーザーが気にする必要はありません。ただし、サードパーティが作成したメモリを読み込む場合は、どのような読み込みルールを使用しているかを確認してください。

共有メモリは同じ PC でしか使用できない(これはデメリット)ですが、他の方法と比較して優れた読み書き速度を提供するため、大きなメッセージをやり取りするのに適しています。

現在、このプロトコルは Windows でのみ利用できます。

Create Protocol Shared Memory

パラメータ説明
Shared Memory Name共有メモリの識別名
Shared Memory Size共有メモリのサイズ(バイト単位)

共有メモリの特徴

項目説明
再送機能なし
常時接続なし
相性の良い分割ルールFixedLength, Terminate, SizeBody (Nodivisionは向いていない)
注意点Windowsでのみ使用可能
注意点受信側がポーリングする必要があるため、送信値がスキップされる可能性あり

ファイル書き込み、読み込み

ファイルは、特定のファイルにメッセージの書き込みと読み込みを行うプロトコルです。

動作は共有メモリと似ていますが、実際のファイルに書き込むため、アプリケーションが終了した後でもメッセージを確認できます。

そのため、何かのデータを保存しておく必要がある用途に適しています。

Create Protocol Log Writer

パラメータ説明
File Path書き込み先のファイルパス
Path Is Absoluteファイルパスが絶対パスかどうか

Create Protocol Log Reader

パラメータ説明
File Path読み込むファイルパス
Path Is Absoluteファイルパスが絶対パスかどうか
Cut First Interval初回の読み込み間隔をスキップするか

Fileの特徴

項目説明
再送機能なし
常時接続なし
相性の良い分割ルールFixedLength, Terminate, SizeBody (Nodivisionは向いていない)
注意点受信側がポーリングする必要があるため、送信値がスキップされる可能性あり

リフレクション

これは自分自身でメッセージの送受信を行うプロトコルです。メッセージが送信されると、同じインスタンス上で受信イベントが発生します。そのため、他のインスタンスとメッセージを交換することはできません。

主に開発時のデバッグ目的で使用されることを想定しています。

リフレクションの特徴

項目説明
再送機能なし
常時接続なし
相性の良い分割ルールなんでも
注意点デバッグ用

パケット分割ルールの切り替え

TCP/IP などのプロトコルでは、単一のメッセージが複数のパケットに分割されることや、逆に複数のメッセージが単一のパケットにまとめられることがあります。

これに対処するため、ObjectDeliverer はパケット分割ルールを設定してこの問題を解決できます。

プロトコルの切り替えと同様に、Start メソッドに渡すことでパケット分割ルールを指定できます。

Blueprint

C++

// UDP 送信者
deliverer->Start(UProtocolFactory::CreateProtocolUdpSocketSender("192.168.0.100", 9099),
UPacketRuleFactory::CreatePacketRuleSizeBody());

ObjectDeliverer は以下の分割ルールをサポートしています。独自のカスタムルールを作成することも可能です。

  • FixedLength
  • Terminate
  • SizeBody
  • Nodivision

送信者と受信者は同じ分割ルールを使用する必要があります。

そのため、サードパーティが作成したプログラムと通信する必要がある場合は、どの分割ルールを使用しているかを事前に確認してください。

FixedLength

FixedLength は、各メッセージに固定の長さを設定してメッセージを分割する方法です。すべての送信でパケットサイズが固定されるため、分割ロジックがシンプルになります。ただし、指定したサイズより大きなメッセージは送信できないという制限があります。

Create Packet Rule Fixed Length

パラメータ説明
Fixed Size固定パケットサイズ(バイト単位)

Terminate

Terminate は、特定の値を区切り文字として指定してメッセージを区切る方法です。よく使われる例として、改行文字を使ってメッセージを区切る方法があります。この方法では、送信するメッセージの長さを動的に変更できますが、毎回終了値を検索する必要があるため、パフォーマンスがわずかに低下します。

Create Packet Rule Terminate

パラメータ説明
Terminate終端文字列(区切り文字) 指定されない場合は改行コード\r(0x0d)\n(0x0a)が使われます

SizeBody

SizeBody は、メッセージの先頭にメッセージサイズを埋め込む方法です。この方法では、メッセージサイズを動的にでき、パケット分割のロジックも比較的シンプルなため、優れたパフォーマンスも提供します。

Create Packet Rule Size Body

パラメータ説明
Size Lengthサイズ情報のバイト数(1, 2, 4, 8)
Size Buffer Endianエンディアン(Big または Little)

Nodivision

Nodivision は、受信した各パケットをパケットの分割や結合を行わずに、そのまま単一のメッセージとして扱います。

Create Packet Rule Nodivision

パラメータ説明
なしこのルールにはパラメータがありません

DeliveryBox の切り替え

デフォルトでは、ObjectDeliverer はバイト配列の送受信を行いますが、これを指定した形式のデータに変換できます。

この機能を使用することで、毎回手動でデータをバイト配列に変換する必要がなくなります。

Note

DeliveryBoxを使用する場合はデータの送信と受信はObjectDelivererManagerではなくDeliveryBoxを経由するように変わることに注意してください

Blueprint

C++

auto deliverybox = UDeliveryBoxFactory::CreateObjectDeliveryBoxUsingJson(SampleObject::StaticClass());
deliverybox->Received.AddDynamic(this, &UMyClass::OnReceiveObject);

deliverer->Start(UProtocolFactory::CreateProtocolTcpIpServer(9099),
UPacketRuleFactory::CreatePacketRuleSizeBody(), deliverybox);

Blueprint

C++

auto message = NewObject<SampleMessage>();
deliveryBox->Send(message);

ObjectDeliverer は以下の DeliveryBox をサポートしています。独自のカスタム DeliveryBox を作成することも可能です。

  • ObjectDeliveryBoxUsingJson
  • Utf8StringDeliveryBox

ObjectDeliveryBoxUsingJson

ObjectDeliveryBoxUsingJson は、任意のユーザー定義 UObject クラスを JSON 文字列に変換して送受信を行う DeliveryBox です。

Unreal Engine で使用できるすべてのクラスは UObject を継承しているため、多くのクラスインスタンスをそのまま送受信できます。

JSON 形式で通信メッセージを交換することは他のプログラミング言語でも一般的なアプローチなので、これを使用することで他のアプリケーションとのメッセージ送受信も可能になります。

このDeliveryBoxについての詳細はこちらを参照してください。

Utf8StringDeliveryBox

Utf8StringDeliveryBox は、任意の文字列をそのまま送受信するための DeliveryBox です。エンコーディングは UTF-8 を使用して行われます。

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

ネットワーク通信は送信側と受信側が同じルールで通信をおこなうことが必要です。

ルールが合わないと通信はうまくいきません。

そこでプラグインをご購入される前にObjectDelivererの通信を試すことができるTesterアプリケーションを用意しました。

このTesterアプリケーションはObjectDelivererの多くの機能を試すことができます。(一部未実装の機能もあります)

これを使って、あなたがUnrealEngineと通信したいアプリケーションやデバイスとObjectDelivererが通信可能か確認してください。

このアプリケーションはObjectDelivererを使って作られているので、このアプリケーションが通信可能ならObjectDelivererも通信可能である可能性が高いです。

このページからテスターアプリをダウンロードできます。

また、このアプリは全てBlueprintで実装されています。またこのブループリントはプラグインに含まれているため、購入後に確認することも可能です。

Sample実装

v1.8.0以降からプラグインの中に各通信プロトコルの実装サンプルを含めています。

各サンプルは1つのプロトコルに対して、1つのActorが用意されていて実際に動作するブループリントが含まれています。

Pluginに含まれるサンプルを確認するには、エディターのContent Browserの設定で"Plugin Content"を有効にしてください。

FAQ

よくある質問はこちらで確認できます。

レビューをお寄せください

このプラグインをご利用いただきありがとうございます。Epic Games Fabストアでのレビューは、今後の開発の大きな励みになります。ぜひご感想をお聞かせください!

Fabストアでレビューを書く