MRが楽しい

MRやVRについて学習したことを書き残す

Blender標準テクニック[ローポリキャラクター制作で学ぶ3DCG]を試す その28(チェッカー選択解除)

本日は書籍「Blender標準テクニック[ローポリキャラクター制作で学ぶ3DCG]」の実施枠です。

ドレス衣装モデリングの続きです。
f:id:bluebirdofoz:20180110011655j:plain
今回はスカートに大きなフリルを作成していきます。

スカートのフリルはモディファイアを利用して作成するので、別オブジェクトとして作成します。
まず、スカートの上部(黒色の箇所)を選択して、Shift+Dキーで複製します。
f:id:bluebirdofoz:20180110011705j:plain

その状態でオブジェクトの分割(Pキー)を選択し、新しいオブジェクトを作成します。
f:id:bluebirdofoz:20180110011714j:plain

オブジェクトを分割したら、ミラーモディファイアと厚み付けモディファイアを設定します。
厚み付けモディファイアは以下の通り設定します。
 幅:0.0750
 均一な厚さ:チェック
 高品質な法線:チェック
 ふちに面を張る:チェック
f:id:bluebirdofoz:20180110011724j:plain

一旦、モディファイアを全て適用します。
f:id:bluebirdofoz:20180110011732j:plain

オブジェクトを作成したら、淵以外の部分を削除します。
まずは面のAlt選択で、淵の部分を選択します。
f:id:bluebirdofoz:20180110011740j:plain

選択範囲の反転(Ctrl+Iキー)で淵以外の部分の選択状態にします。
f:id:bluebirdofoz:20180110011748j:plain

この状態で DELキー -> 面 で面の削除を行います。
f:id:bluebirdofoz:20180110011757j:plain

見えない部分に不要な面が残っている場合があるので、確認して削除を行います。
f:id:bluebirdofoz:20180110011806j:plain

淵の部分のみになった面に対し再び、厚み付けモディファイアを適用します。
この厚みがフリルの厚みになります。以下の通り設定します。
 幅:-0.2000
 均一な厚さ:チェック
 高品質な法線:チェック
 ふちに面を張る:チェック
 ふちのみ:チェック
f:id:bluebirdofoz:20180110011814j:plain
面の法線方向へ厚みを伸ばすので、幅の設定はマイナス値にすることに注意します。

モディファイアを適用します。
合わせて、フリル部分が分かりやすいようにマテリアルを変更します。
f:id:bluebirdofoz:20180110011823j:plain

以降は再びミラーモディファイアを用いて編集するため、左半分のメッシュを選択して削除します。
f:id:bluebirdofoz:20180110011831j:plain

更に必要となる表面以外のメッシュも削除します。
f:id:bluebirdofoz:20180110011843j:plain

すると以下のようなフリル用のメッシュが作成されます。
f:id:bluebirdofoz:20180110011852j:plain

次にメッシュの細分化を行います。始めに全ての上辺と下辺を選択します。
f:id:bluebirdofoz:20180110011900j:plain

Wキー -> 細分化 を繰り返し、メッシュを分割していきます。
f:id:bluebirdofoz:20180110011908j:plain

不要に増えた辺は以下のように辺のAlt選択から DELキー -> 辺を融解 で削除します。
f:id:bluebirdofoz:20180110012020j:plain

フリル用の細分化メッシュが出来たら、次はフリルの高低差を作り込みます。
まずは下辺をAlt選択し、この状態で 選択 -> チェッカー選択解除 を実行します。
f:id:bluebirdofoz:20180110012029j:plain

するとツールシェフに「チェッカー選択解除」が表示されるので「N番目を選択」の値を 4 に設定します。
f:id:bluebirdofoz:20180110012038j:plain
これで3つ飛ばしで辺を選択した状態になります。

この状態で法線方向へのサイズ拡大(Alt+Sキー)を行います
f:id:bluebirdofoz:20180110012046j:plain

チェッカー選択解除は接続された辺でしか行えないので同様の手順を全てのフリルに行います。
f:id:bluebirdofoz:20180110012055j:plain

最後にフリルの各辺の長さを調節します。
チェッカー選択解除を用い、オフセットなどを選択して法線方向に押し出している辺を選択します。
f:id:bluebirdofoz:20180110012102j:plain

ピボットポイントを「それぞれの原点」に設定した状態で拡大縮小(Sキー)を用いて各辺の長さを調節します。
f:id:bluebirdofoz:20180110012110j:plain

調整を行えば、フリルの完成です。
f:id:bluebirdofoz:20180110012118j:plain

Blender標準テクニック[ローポリキャラクター制作で学ぶ3DCG]を試す その27(両辺での細分化)

本日は書籍「Blender標準テクニック[ローポリキャラクター制作で学ぶ3DCG]」の実施枠です。

ドレス衣装モデリングの続きです。
f:id:bluebirdofoz:20180109004038j:plain
今回は服のフリルの作りこみの続きです。

ドレスの下部のフリルを作成します。
こちらは押出作成をしていなかったので、書籍の手順通りのフリル作成を行います。
フリルを作成する淵の部分でループカット(Ctrl+Rキー)を実行し、淵とフリル部分を切り分けます。
f:id:bluebirdofoz:20180109004050j:plain

フリルを作成する両辺を選択し、Wキー -> 細分化 を実行します。
f:id:bluebirdofoz:20180109004112j:plain

すると以下のように丁度半分割の位置でメッシュがカットされます。
f:id:bluebirdofoz:20180109004119j:plain

これを繰り返し、フリル用のメッシュを切り分けます。
f:id:bluebirdofoz:20180109004129j:plain

後は前回同様、各頂点を選択し、分割(Vキー)を実施していきます。
f:id:bluebirdofoz:20180109004138j:plain

両端の頂点を選択し、Alt+Mキー -> 中点 で結合します。
f:id:bluebirdofoz:20180109004147j:plain

最後にまとめてベベル(Ctrl+Shift+Bキー)で丸めます。
f:id:bluebirdofoz:20180109004156j:plain

調整を行って完了です。
f:id:bluebirdofoz:20180109004207j:plain
細かい作業のため根気が要りますが、細かく凝れば凝るほど絵の説得力が増すように思います。

SharingWithUNETについてまとめる その5

本日は HoloToolKit の調査枠です。
SharingWithUNET のサンプルシーンを確認していきます。
bluebirdofoz.hatenablog.com

今回は Manager オブジェクトにある GenericNetworkTransmitter について機能を確認します。
f:id:bluebirdofoz:20180108224901j:plain

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.");
            }
        }

Blender標準テクニック[ローポリキャラクター制作で学ぶ3DCG]を試す その26(フリルの作成)

本日は書籍「Blender標準テクニック[ローポリキャラクター制作で学ぶ3DCG]」の実施枠です。

ドレス衣装モデリングの続きです。
f:id:bluebirdofoz:20180107230251j:plain
今回は靴と服のフリルを作りこみます。

最初に靴の作りこみです。
エッジループ(Ctrl+Rキー)とナイフツール(Kキー)で靴の形を整えます。
f:id:bluebirdofoz:20180107230310j:plain

踵の部分を押出(Eキー)でヒールを作れば靴は完了です。
f:id:bluebirdofoz:20180107230326j:plain

次に服のフリルを作りこみます。まずは上部ドレスからです。
書籍ではループカット(Ctrl+Rキー)を利用してフリル部分と淵を分割しています。
しかし自分の場合、淵を押出で立体的に作成していたので、辺の押出(Eキー)でフリルの面を追加する形にしました。
f:id:bluebirdofoz:20180107230341j:plain

追加した面をナイフ(Kキー)で分割し、フリル用の面を作成していきます。
f:id:bluebirdofoz:20180107230354j:plain

後はフリル外側の頂点を分割(Vキー)と結合(Alt+Mキー)で整え、三角形のフリルを作成します。
f:id:bluebirdofoz:20180107230407j:plain

三角形のフリルを作成したらベベル(Ctrl+Shift+Bキー)で一括で丸みをつけます。
f:id:bluebirdofoz:20180107230441j:plain

マテリアルを設定したら上部ドレスのフリルが完成です。
f:id:bluebirdofoz:20180107230504j:plain

SharingWithUNETについてまとめる その4

本日は HoloToolKit の調査枠です。
SharingWithUNET のサンプルシーンを確認していきます。
bluebirdofoz.hatenablog.com

今回は Manager オブジェクトにある WorldAnchorManager について機能を確認します。
f:id:bluebirdofoz:20180106005824j:plain

WorldAnchorManager は作成したワールドアンカーをストアに保存・管理を行います。
SharingWithUNET では作成したアンカー、または、サーバから受信したアンカーをローカルで保持するために用いられます。

自作アプリを組み込む際にはひとまずノータッチでも問題なさそうです。

Anchor Debug Text

アンカー処理のデバッグテキストを TextMesh に表示する。
シーン内の TextMesh オブジェクトを設定することで、シーン内でデバッグメッセージが確認可能。

Show Detailed Logs

コンソールウィンドウでの詳細なログを有効にする。

Persistent Anchors

後続のゲームセッションからアンカーを保存できるようにする。

SharingWithUNETについてまとめる その3

本日は HoloToolKit の調査枠です。
SharingWithUNET のサンプルシーンを確認していきます。
bluebirdofoz.hatenablog.com

今回は UNETSharingStage オブジェクトにある NetworkDiscoveryWithAnchor について機能を確認します。
f:id:bluebirdofoz:20180105223519j:plain

NetworkDiscoveryWithAnchor はブロードキャスト送信で共有アンカーの管理を行います。
サーバの場合、アンカーの作成と他クライアントへのブロードキャスト処理を開始します。
クライアントの場合、サーバからのブロードキャスト受信処理を開始します。
スクリプトはNetworkDiscovery コンポーネントを継承しています。

ただし実際にアンカーデータの送受信を実行するのは GenericNetworkTransmitter です。
スクリプトはサーバ、クライアントのIPアドレス検出まで実行します。

自作アプリを組み込む際にはひとまずノータッチでも問題なさそうです。

Broadcast Port

ブロードキャストを行い、リッスンするネットワークポート

Broadcast Key

ブロードキャストでこのアプリケーションを識別するキー

Broadcast Version

ブロードキャストするアプリケーションのバージョン。
同じアプリケーションのバージョンと一致させるために使用される。

Broadcast SubVersion

ブロードキャストするアプリケーションのサブバージョン。
同じアプリケーションのバージョンと一致させるために使用される。

Broadcast Interval

サーバーを走らせているときのブロードキャストする頻度(ミリ秒)

Use NetworkManager

ネットワークマネージャーと統合する場合、 True 。
サーバーとして実行しているとき、ブロードキャストメッセージにネットワークマネージャーのアドレスが含まれる。
クライアントとして実行しているとき、 NetworkManager を使用して見つかったマッチングゲームに参加できる。

Broadcast Data

サーバーとして実行しているとき、ブロードキャストメッセージに含めるデータ
NetworkManager インテグレーションを使用すると NetworkManager のアドレスで上書きされる。

Show GUI

デフォルトの Broadcast Control UI を描画する場合、True。

参考ページ
docs.unity3d.com


サーバ側の初期化処理
HoloLens 上では UNetAnchorManager にアンカーの作成を依頼します。
・NetworkDiscoveryWithAnchors.cs

        /// <summary>
        /// サーバを初期化する。
        /// </summary>
        /// <returns></returns>
        private IEnumerator InitAsServer()
        {
            Debug.Log("Acting as host");
#if !UNITY_EDITOR && UNITY_WSA
            // NetworkManagerに自身のIPアドレスをサーバアドレスとして設定する。
            NetworkManager.singleton.serverBindToIP = true;
            NetworkManager.singleton.serverBindAddress = LocalIp;
#endif
            // ※ yield return null (コルーチン)の役割。
            //    return null はココで処理を中断するということです。
            //    Unityでは、1フレーム分中断して、次のフレームで続きの行の処理を行います。

            // StopBroadcast will also 'StopListening'
            // ブロードキャストの実行と受信を停止する。
            StopBroadcast();

            // Work-around when building to the HoloLens with "Compile with .NET Native tool chain".
            // Need a frame of delay after StopBroadcast() otherwise clients won't connect.
            // "Compile with .NET Native tool chain" をHoloLensに組み込むときの回避策。
            // StopBroadcast()の後に遅延のフレームが必要です。そうしないと、クライアントは接続しません。
            yield return null;

            // Starting as a 'host' makes us both a client and a server.
            // There are nuances to this in UNet's sync system, so do make sure
            // to test behavior of your networked objects on both a host and a client 
            // device.
            // 「ホスト」として開始することで、自身はクライアントとサーバーの両方になります。
            // UNetのシンクシステムにはホストの動作に微妙な差異があります。
            // ホストデバイスとクライアントデバイスの両方でネットワークオブジェクトの動作をテストするようにしてください。
            NetworkManager.singleton.StartHost();

            // Work-around when building to the HoloLens with "Compile with .NET Native tool chain".
            // Need a frame of delay between StartHost() and StartAsServer() otherwise clients won't connect.
            // "Compile with .NET Native tool chain" をHoloLensに組み込むときの回避策。
            // StartHost()とStartAsServer()の間に遅延のフレームが必要です。さもなくばクライアントが接続しません。
            yield return null;

            // Start broadcasting for other clients.
            // 他のクライアントへのブロードキャストを開始します。
            StartAsServer();

#if !UNITY_EDITOR && UNITY_WSA
            // Start creating an anchor.
            // アンカーの作成を開始します。
            UNetAnchorManager.Instance.CreateAnchor();
#else
            // UnityEditor上の動作であればアンカーは作成しません。
            Debug.LogWarning("This script will need modification to work in the Unity Editor");
#endif
        }


クライアント側の初期化処理
HoloLens 上では GenericNetworkTransmitter にアンカーデータを取得するIPアドレスを設定します。
・NetworkDiscoveryWithAnchors.cs

        /// <summary>
        /// Call to join a sessoin
        /// セッションに参加するために呼び出します。
        /// </summary>
        /// <param name="session">Information about the session to join(参加するセッションに関する情報)</param>
        public void JoinSession(SessionInfo session)
        {
            // ブロードキャストを停止する。
            StopListening();
            // We have to parse the server IP to make the string friendly to the windows APIs.
            // 我々は文字列をWindows APIに利用するために、サーバのIPを解析する必要があります。
            // ブロードキャストを送信したシステムのIPアドレスを取得する。
            ServerIp = session.SessionIp;
            // 取得したIPアドレスをNetworkManagerのネットワークアドレスとして登録する。
            NetworkManager.singleton.networkAddress = ServerIp;
#if !UNITY_EDITOR && UNITY_WSA
            // Tell the network transmitter the IP to request anchor data from if needed.
            // 必要に応じてアンカーデータを要求するIPをネットワークトランスミッタに伝えます。
            GenericNetworkTransmitter.Instance.SetServerIp(ServerIp);
#else
            Debug.LogWarning("This script will need modification to work in the Unity Editor");
#endif
            // And join the networked experience as a client.
            // クライアントとしてネットワーク化されたエクスペリエンスに参加する。
            // NetworkManagerをクライアントとして開始する。
            NetworkManager.singleton.StartClient();
            // 接続または切断時に発生するイベントを呼び出す。
            SignalConnectionStatusEvent();
        }

SharingWithUNETについてまとめる その2

本日は HoloToolKit の調査枠です。
SharingWithUNET のサンプルシーンを確認していきます。
・SharingWithUNETについてまとめる その1
 http://bluebirdofoz.hatenablog.com/entry/2018/01/03/225437

今回は UNETSharingStage オブジェクトにある NetworkManager について確認しました。
f:id:bluebirdofoz:20180104225533j:plain

Dont Destroy On Load

シーンが変更するときに NetworkManager オブジェクトが破棄されるかどうかを制御するフラグ
シーンをまたいで 1 つの NetworkManager で管理する場合は、true にする。
各シーンに NetworkManager を配置する場合は、false にする。

Run in Background

バックグラウンドでアプリを起動し続けているときに、プログラムが実行するかどうか
ローカルホストを使用してテスト実行をしている場合は、同じマシン上で複数のネットワークアプリケーションが実行できるように true にする。

Log Level

ネットワークに関するログをユーザーに表示するためのログレベル

Offline Scene

オフライン時に切り替えるシーン
設定すると NetworkManager でシーンの管理を行うことができる。
このシーンはクライアントが切断したときや、サーバーがシャットダウンしたときのような、セッションが完了したときにシーンを切り替える。

Online Scene

オンライン時に切り替えるシーン
設定すると NetworkManager でシーンの管理を行うことができる。
このシーンはクライアントが接続したときや、サーバーをリッスンしたときのような、セッションが開始したときにシーンを切り替える。

Network Info

ネットワークに関する情報を設定する。
f:id:bluebirdofoz:20180104225550j:plain
・Use WebSockets
 - これにより、NetworkServer は通常のトランスポート層接続の代わりに、WebSockets 接続に備えて待機する。
  WebGL クライアントをサーバーに接続可能にする。

・Network Address
 - 現在使用しているネットワークアドレス
  クライアントでは、接続しているサーバーのアドレスになる。サーバーでは、ローカルアドレスになる。

・Network Port
 - 現在使用しているネットワークのポート
  クライアントでは、接続しているサーバーのポートになる。サーバーでは、リッスンポートになる。

・Server Bind To IP
 - 特定の IP アドレスにバインドされているかどうかをサーバーに伝えるためのフラグ
  これが false の場合、特定の IP アドレス(IP_ANY)にバインドされない。

・Script CRC Check
 - サーバーとクライアント間でスクリプトCRC チェックを行うためのフラグ
  クライアントとサーバー間で、NetworkBehaviour のスクリプトが一致するのを保証するために CRC チェックを有効にする。
  これは、クライアントとサーバーで異なる Unity プロジェクトを利用している場合はあまり適切ではない。

・Max Delay
 - 接続のパケットを送信する前にかける最大ディレイ
  秒単位で設定される。デフォルトでは 0.01 秒、つまり、10 ミリ秒の遅延が発生する。
  0 に設定すると、HLAPI 接続のバッファリングを無効にする。

・Max Buffered Packets
 - 未調査。

・Packet Fragmentation
 - 未調査。

・MatchMaker Host URI
 - マッチメイキングサーバーのホスト名

・MatchMaker Port
 - マッチメイキングサーバーのポート

・Match Name
 - 現在のマッチ名
  現在進行中のマッチ名を示すテキスト文字列

・Maximum Match Size
 - 現在のマッチの最大プレイヤー数

Spawn Info

シーン内のゲームオブジェクトに関する情報を設定する。
f:id:bluebirdofoz:20180104225610j:plain
・Player Prefab
 - サーバー上でプレイヤーオブジェクトを作成するときに使用されるデフォルトのプレハブ
  プレイヤーオブジェクトは、サーバー上の AddPlayer() のデフォルト処理で作成される。
  この動作は OnServerAddPlayer を実装することでオーバーライドすることができる。

  SharingWithUNET では Assets/HoloToolkit/SharingWithUNET/Prefabs 配下にある Pleyer.prefab を Player Prefab として利用する。
f:id:bluebirdofoz:20180104225628j:plain

・Auto Create Player
 - 接続時や、シーンの変更時に自動でプレイヤーオブジェクトを作成するかどうかを制御するフラグ

・Player Spawn Method
 - NetworkManager で使用される、プレイヤーを生成する方法
  Random:プレイヤーの生成位置をランダムで決めます
  RoundRobin:指定の生成位置でプレイヤーを生成します。

・Registered Spawnable Prefabs
 - サーバー上でオブジェクトを生成するときに使用されるプレハブ
  本オブジェクトはSpawn()の処理で生成される。

  SharingWithUNET では Assets/HoloToolkit/SharingWithUNET/Prefabs 配下にある NetBullet.prefab をオブジェクトとして利用する。
f:id:bluebirdofoz:20180104225644j:plain

Advanced Configuration

チェックすると、送信データの設定などの拡張設定が行える。
f:id:bluebirdofoz:20180104225657j:plain

Use Network Simulator

チェックすると、レイテンシとパケットロスに関するシミュレーションを行える。
f:id:bluebirdofoz:20180104225706j:plain


自作アプリを組み込む際にはまず Spawn Info に関する部分に手を加える必要がありそうです。


参考ページ
unity3d.com
docs.unity3d.com
docs.unity3d.com