UnrealEngineをWebSocketのClientにする
わ、前回更新から1年以上経ってしまった....
はじめに
UnrealEngineと書いたのは、UE4・UE5どちらでも大丈夫だと思うため。
というわけで、Go製のWebServerに対してUnrealEngineからWebSocketを経由で通信するサンプルを作りました。
これの解説を行います。(今回はUE5でいきます)
完成イメージ
プラグインにGameInstanceSubsystemを継承したSubsystemを作成し、その中でWebSocketをServerへつなげて、Serverからメッセージを受け取ります。
それをEventDispatcherにしたので、以下の画像のように使うことができます。
解説
WebServer
github.com/gorilla/websocket
のcommand exampleを参考に書きました。
ここの解説は上記のリンクに譲ろうと思います。
UnrealEngine
まず初めに、.Build.cs
ファイルの依存モジュールにWebSockets
を追加します。
PublicDependencyModuleNames.AddRange( new string[] { "Core", // ... add other public dependencies that you statically link with here ... "WebSockets", // 例えばこんな感じ } );
続いてSubsystemを作成します。
とりあえずは常時存在してほしいので、GameInstanceSubsystemを継承したクラスで作成します。
headerの完成形はこちら
UnrealWebSock_Sample/WebsocketSampleSubsystem.h at master · crssnky/UnrealWebSock_Sample · GitHub
一部解説していきます。
9行目:IWebSocket
を前方宣言します。
11行目:このプラグイン専用のLogカテゴリを宣言します。
12行目:メッセージを受信した際に発火するイベントを宣言します。
22,33行目:UGameInstanceSubsystem
のInit, Deinit関数をOverrideします。
25,26行目:最後に受け取ったメッセージを取得する関数を宣言します。
29,30行目:BlueprintからBindできる、メッセージを受信した際に発火するイベントオブジェクトを宣言します。
33~36行目:ソケットオブジェクトのためのイベント関数を宣言します。
38行目:ソケットオブジェクトを宣言します。
39行目:最後に受け取ったメッセージを保持する。
sourceの完成形はこちら
UnrealWebSock_Sample/WebsocketSampleSubsystem.cpp at master · crssnky/UnrealWebSock_Sample · GitHub
void UWebsocketSampleSubsystem::Initialize(FSubsystemCollectionBase& Collection)
Socketオブジェクトを作成し、各種イベントに関数をバインドしていきます。
オブジェクト作成には、WebServerのURIやサブプロトコルws
を入れます。
(本来ならばサブプロトコルはちゃんとするべきですが、テスト用でサーバー側に処理がなく、以下のようなエラー文を経由するため、何かしらを入れておく必要があります)
UE_LOG(LogWinHttp, Warning, TEXT("Attempted to create a WinHttp WebSocket with an empty protocols list"));
設定が終わったら、最後に接続します。
void UWebsocketSampleSubsystem::Deinitialize()
GameInstanceが消える前に、Socketを切断してメモリ領域を開放します。
FString UWebsocketSampleSubsystem::CurrentMessage() const
最後に受け取ったメッセージを取得する関数です。
void UWebsocketSampleSubsystem::OnSocketConnected() const
Socketが接続したときに呼ばれる関数です。
とりあえず確認用に、ログを吐きます。
void UWebsocketSampleSubsystem::OnSocketConnectioinError(const FString& err) const
Socketの接続に失敗したときに呼ばれる関数です。
とりあえず確認用に、Warningレベルで理由を出力します。
void UWebsocketSampleSubsystem::OnSocketClosed(const int statusCode, const FString& reason, const bool wasClean) const
Socketが切断したときに呼ばれる関数です。 とりあえず確認用に、ログを吐きます。
void UWebsocketSampleSubsystem::OnSocketMessageReceived(const FString& msg)
Socketがメッセージを受信したときに呼ばれる関数です。
受け取ったメッセージを保持し、そのメッセージをイベント発行します。
おわりに
本当に、簡単にWebsocketを繋げてメッセージを受信することができました。
ミニマムで言えば、Initialize
・Deinitialize
・OnSocketMessageReceived
のみを実装するだけで良いので、本当に簡単です。
何かしらのWebサービスと繋げることも難しくありません。何かの可視化ツールとしても使ってみるのはいかがでしょうか?