本日は HoloToolKit の調査枠です。
SharingWithUNET のサンプルシーンを確認していきます。
bluebirdofoz.hatenablog.com
今回は Manager オブジェクトにある GenericNetworkTransmitter について機能を確認します。
GenericNetworkTransmitter は作成したワールドアンカーデータの送受信を行います。
接続先のサーバのIPアドレスは NetworkDiscoveryWithAnchor スクリプトが検出し、本スクリプトの SetServerIp() に通知します。
サーバのIPアドレスに対して、接続要求を一定間隔で実施します。
サーバ側は UNetAnchorManager スクリプトがアンカーデータのシリアル化の完了と共に、本スクリプトの ConfigureAsServer() をキックしてソケットリスナーを起動します。
自作アプリを組み込む際にはひとまずノータッチでも問題なさそうです。
ただ、本スクリプトと UNetAnchorManager スクリプトはシェアリングのワールドアンカーの取り扱いをまとめたスクリプトですので、理解を深めて損はなさそうです。
Send Connection Port
アンカーデータの送受信を行うポート番号を指定する。
/// <summary> /// Tells us who to contact if we need data. /// データが必要な場合に、連絡先を教えます。 /// </summary> /// <param name="newServerIp"></param> public void SetServerIp(string newServerIp) { serverIp = newServerIp.Trim(); } /// <summary> /// Configures the network transmitter as the source. /// ネットワークトランスミッタをソースとして設定します。 /// </summary> public void ConfigureAsServer() { #if !UNITY_EDITOR && UNITY_WSA Task t = new Task(() => { // ソケットリスナーを作成する。 networkListener = new StreamSocketListener(); // 接続時のイベント関数として NetworkListener_ConnectionReceived を登録する。 networkListener.ConnectionReceived += NetworkListener_ConnectionReceived; // StreamSocketListenerのバインド操作をローカルサービス名に開始する。 networkListener.BindServiceNameAsync(SendConnectionPort.ToString()).GetResults(); } ); t.Start(); #else Debug.Log("This script is not intended to be run from the Unity Editor"); // In order to avoid compiler warnings in the Unity Editor we have to access a few of our fields. // Unity Editorでコンパイラの警告を避けるために、いくつかのフィールドにアクセスする必要があります。 Debug.Log(string.Format("serverIP = {0} waitingForConnection = {1} mostRecentDataBuffer = {2}", serverIp, waitingForConnection, mostRecentDataBuffer == null ? "No there" : "there")); #endif } #if !UNITY_EDITOR && UNITY_WSA /// <summary> /// When a connection is made to us, this call back gets called and /// we send our data. /// 私たちとの接続が確立されると、このコールバックが呼び出され、データが送信されます。 /// </summary> /// <param name="sender">The listener that was connected to.(接続されたリスナー)</param> /// <param name="args">some args that we don't use.(私たちが使用していない幾つかの引数)</param> private void NetworkListener_ConnectionReceived(StreamSocketListener sender, StreamSocketListenerConnectionReceivedEventArgs args) { // If we have data, send it. // データがある場合は送信する。 if (mostRecentDataBuffer != null) { // データバッファにデータがある場合 // 出力ストリームを取得する。 IOutputStream stream = args.Socket.OutputStream; // ストリームにデータを書き込む。 using (DataWriter writer = new DataWriter(stream)) { // 先頭32ビットにデータ長を設定する writer.WriteInt32(mostRecentDataBuffer.Length); // データバッファの内容を設定する。 writer.WriteBytes(mostRecentDataBuffer); // バッファーのデータをコミットする。 writer.StoreAsync().AsTask().Wait(); // バッファーをクリアして書き込む。 writer.FlushAsync().AsTask().Wait(); } } else { // 送信するデータはありませんが、接続されています。これは予期しないことです。 Debug.LogError("No data to send but we've been connected to. This is unexpected."); } }