UNetWebSocket
UnityのUNET勉強がてら作ったテスト用プログラム。
ソースコード:https://github.com/nQuantums/UNetWebSocket
説明
UNETを構成するクラスが多くていまいちわからなかったので勉強のために作成しました。
- メモ代わりのプログラムのため無駄にコメントを記述してあります。
- 勉強のため敢えてNetworkManagerを使用していません。サーバー側とクライアント側でクラスを分けています。
- ネットワーク越しの物理挙動の同期の確認を目的にしています。
- 装甲車(?)を操作し、ミサイル&グレネードを発射して挙動を確認できます。
デモ画面
テスト用サイト ※サーバーいつ止めるかわかりません
要求環境
- Unity5.6以上
今回使ったUNETクラス一覧&概略
-
NetworkInstanceId
- サーバー&クライアント上で同じ要素を認識するためのID。
- ClientScene.FindLocalObject に渡すとオブジェクト取得できる。今回のプログラムでは弾の発射主と接触判定行わないようにするために使用。
-
NetworkIdentity コンポーネント
- NetworkInstanceId を保持している。
- サーバー&クライアント間で状態同期させたいならこのコンポーネントをセットする必要がある。
- このコンポーネントをセットしたオブジェクトをシーンに配置すると勝手にDeactivate状態になっているため自分でSetActive(true)を呼び出す必要がある。
-
NetworkBehaviour コンポーネント
- サーバー&クライアント間で状態同期やら処理する自作クラスはこれを継承する。
- SyncVar 属性を付与したフィールドを持たせたいなら継承する必要がある。ちなみにこの属性が付与されたフィールドはサーバー&クライアント間で同期される。
-
NetworkTransform コンポーネント
- 位置と角度を同期させる。
-
NetworkIdentity.localPlayerAuthority の値により、クライアントとサーバーで以下の様に挙動が異なる。
- クライアント側の所有オブジェクト(プレイヤーなど?)の場合はクライアント側で物理挙動等を計算し、計算結果をサーバーへ転送する。
- サーバー側の所有オブジェクトの場合はサーバー側で物理挙動等を計算しクライアントにブロードキャストされる、これは敵ユニット等のクライアント側の所有オブジェクトでない場合の共通挙動らしい。
- transformSyncMode プロパティで位置&角度のみ同期か、Rigidbody2D/Rigidbody3Dでの物理演算も含めた同期か決定するみたい。
-
NetworkServer
- サーバー側での接続待ち受け&接続管理クラス、シングルトン。
- 使い方、今回のプログラムでは Awake() 内で以下の様にやっている・・・
- NetworkServer.useWebSockets = true によりWebSocketを使う設定にする。
- NetworkServer.RegisterHandler(MsgType.Connect, OnConnect) を呼び出してクライアントから接続された際のイベントハンドラ登録。
- NetworkServer.RegisterHandler(MsgType.AddPlayer, OnAddPlayer) を呼び出してプレイヤーオブジェクトを生成するハンドラ登録。
- NetworkServer.RegisterHandler(MsgType.Disconnect, OnPlayerDisconnect) を呼び出してクライアント切断時のイベントハンドラ登録。
- NetworkServer.Listen(port) を呼び出して接続受付開始。
-
NetworkClient クラス
- クライアント側からサーバーへ接続するためのクラス。
- 使い方、とりあえず Start() 内で以下の様にする・・・
- _client = new NetworkClient() でオブジェクト作成。
- _client.Connect(address, port) でサーバーに接続。
- _client.RegisterHandler(MsgType.Connect, OnClientConnected) で接続できた際のイベントハンドラ登録。
-
ClientScene クラス
- クライアント側でのシーンに関する情報を保持するシングルトン。
- 今回プログラムでの使い方・・・
- Start() 内で RegisterSpawnHandler 呼び出して NetworkIdentity コンポーネントセットされたオブジェクトの生成、破棄ハンドラを登録する。※これはオブジェクト生成時に何か処理したい場合に使うが、普通は RegisterPrefab の方を使うらしい。
- 上記の _client.RegisterHandler で登録した OnClientConnected 内で ClientScene.Ready(netMsg.conn) 呼び出してサーバーにクライアント側の準備ができたことを通知。
- ClientScene.AddPlayer(0) を呼び出してクライアント接続毎のID登録。
使い方
Linuxでのサーバー起動例
sudo nohup ./UNetWebSocket.x86_64 -server -batchmode -nographics -logfile ulog.txt > out.log 2> err.log < /dev/null &