【Unity】Node.jsのサーバにWebSocketを使ってデータを送信
2018-12-22 2019-05-21
Pref.
UnityからNode.jsで動かしてるサーバにオブジェクトの座標を送ってみたかったんです.こちらの @oishihiroaki さんの記事を参考にwebsocket-sharpをUnityに入れてやってみたのでまとめます.ありがとうございます(๑•̀ㅂ•́)و✧ 以下に今回作ったサンプルプロジェクトを置いておきました. https://github.com/nmxi/UnityWebSocketTest
Env.
Windows10 64bitUnity 20181.5f1
Node v8.11.3
Method
1.Unityに2つのライブラリをインポート
こちらの記事を参考にまずwebsocket-sharpをUnityに入れます. 上記の記事の中ではMonoDeveropを利用してビルドし,dllファイルを生成しているのですが,Unity2018からエディタがVisual Studioになったので(?)今回はそちらの方法を簡単に書き残しておきます.簡単ですがw まずGitHubからCloneかZipで保存しまして,websocket-sharp.slnをVisual Studioで開きます.

websocket-sharp.dllが生成されます.

これで,erbsocket-sharpのUnityへのインポートは完了です. 今回UniRXもインポートしました.
UniRxは非同期処理においてはちゃめちゃ便利なライブラリです.
アセットストアからインポートインポートして下さい. https://assetstore.unity.com/packages/tools/integration/unirx-reactive-extensions-for-unity-17276


2.UnityでWebSocketクライアントを作る
- Unity上のオブジェクトの3次元座標情報をNode.jsで動かしているサーバに送信
- オブジェクトの座標に変化があったときだけサーバに情報を送信
- Box
- Button 2つ

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
using System.Collections; using System.Collections.Generic; using UnityEngine; using WebSocketSharp; using UniRx; public class PositionSync : MonoBehaviour { [SerializeField] private string _serverAddress; [SerializeField] private int _port; [SerializeField] private Transform _syncObjTransform; //Share transform [SerializeField] private SyncPhase _nowPhase; private WebSocket ws; public enum SyncPhase { Idling, Syncing } private void Awake() { _nowPhase = SyncPhase.Idling; var cTransformValue = gameObject.ObserveEveryValueChanged(_ => _syncObjTransform.position); cTransformValue.Subscribe(x => OnChangedTargetTransformValue(x)); } /// <summary> /// Get Down Start Sync Button /// </summary> public void OnSyncStartButtonDown() { var ca = "ws://" + _serverAddress + ":" + _port.ToString(); Debug.Log("Connect to " + ca); ws = new WebSocket(ca); //Add Events //On catch message event ws.OnMessage += (object sender, MessageEventArgs e) => { print(e.Data); }; //On error event ws.OnError += (sender, e) => { Debug.Log("WebSocket Error Message: " + e.Message); _nowPhase = SyncPhase.Idling; }; //On WebSocket close event ws.OnClose += (sender, e) => { Debug.Log("Disconnected Server"); }; ws.Connect(); _nowPhase = SyncPhase.Syncing; } /// <summary> /// Get Down Stop Sync Button /// </summary> public void OnSyncStopButtonDown() { ws.Close(); //Disconnect } public void OnChangedTargetTransformValue(Vector3 pos) { if (_nowPhase == SyncPhase.Syncing) { Debug.Log(pos); ws.Send(pos.ToString()); } } } |
以上のスクリプトでは
オブジェクトのTransform.positionに変化があったとき & Enumで定義したSyncPhase _nowPhaseがSyncingのとき サーバ側にVector3をstring型にして送信しています.
余談ですが「この値が変化したとき」といったときの処理にUniRxを使っています. このスクリプトをEmptyObjectなどをMasterとかに名前を変えて空のオブジェクトを作成して,コンポーネントとして追加します.
コンポーネントを追加したら,サーバアドレスとポート,座標情報をサーバに送りたいオブジェクトのTransformを変数SyncObjTransformにセットします.サーバアドレスとポートは特に問題がなければ”localhost”と8080を入れておきます.

- PositionSync.OnSyncStartButtonDowns
- PositionSync.OnSyncStopButtonDown

3.Node.jsでWebSocketサーバを作る
Node.jsを予めインストールしておいて下さい.今回私の環境ではv8.11.3を利用しました. 適当なディレクトリに以下のserver.jsを作ります.
1 2 3 4 5 6 7 8 9 10 11 |
var WebSocketServer = require('ws').Server var wss = new WebSocketServer({ port: 8080 }); wss.on('connection', function(ws) { ws.on('message', function(message) { console.log('received: %s', message); }); ws.send('This is server'); }); |
4.動作確認
まずサーバ側を以下コマンドで起動させます.
1 |
$ node server.js |
箱を移動させると…

上の様子ではマウスでドラッグするとボックスが動いていますが,以下の記事を参考させて頂きました.
Ref.
http://neareal.com/1230/https://qiita.com/oishihiroaki/items/bb2977c72052f5dd5bd9
http://hwks.hatenadiary.jp/entry/2014/07/20/022229
http://blog.katty.in/2206