現場が無いならVRで見ればいいじゃない

UnityはPC・スマホのゲーム制作用に限らず、プロジェクションや大型モニターを使ったインスタレーション、体験コンテンツにもよく使われます。

その場に行かないとできない体験は、その場所ならではの特別感にも繋がります。

でも、それ故に製作中に用意することが難しいのが、**現場環境**です。
![genbacat_s.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16457/0c4a2703-42ea-1f86-815d-803f87a926a2.jpeg)

# サンプルケース
例えばこういうケースがあったとします。
![doshite_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16457/1233bf47-2ae2-def6-b658-0fc6160c0336.png)

鳥居がどのくらいの大きさになるのか、プロジェクションの広さはどのくらいになるのか。そもそもどんな見え感になるのか。
本番直前の現場施工のタイミングになって`思ったより小さかった`、`この大きさならもっと違う案ができたのに`なんてことにならないように関係者で認識合わせをしたいものです。

ただ、現場と同じ開発環境が用意できる場合は問題ないですが、オフィス内で製作進める時に鳥居を持ち込むわけにもいきません。

そんな時に便利なのが**VR**。
現実に用意できないものはバーチャルで用意してしまえという発想です。

そして忘れてはならないのが、**UnityはVRが得意**であること。

# 映像を転送してVRで見る

UnityはVRが得意でも、今回のケースで作りたいものはプロジェクションであって、VRではありません。
VR用のシーンやVR用のアセットを、プロジェクション用のプロジェクトに組み込むのは得策ではありません。

そこで、プロジェクションのプロジェクトとVRのプロジェクトを別々で用意します。

プロジェクションのプロジェクトは通常通りに進めておき、VRのプロジェクトでは現場の雰囲気・サイズ感が把握できるVR空間を用意しておきます。

VR空間の中にプロジェクションの映像だけを転送して見ることができれば、本来のプロジェクション用のプロジェクトを乱すことなくVR空間を作れるようになります。

つまりはこうです。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">これを<a href="https://twitter.com/hashtag/Unity?src=hash&amp;ref_src=twsrc%5Etfw">#Unity</a> <a href="https://t.co/ahmnDK1qTk">pic.twitter.com/ahmnDK1qTk</a></p>&mdash; foka (@foka22ok) <a href="https://twitter.com/foka22ok/status/1207998096015183872?ref_src=twsrc%5Etfw">December 20, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

<blockquote class="twitter-tweet" data-conversation="none"><p lang="ja" dir="ltr">ここに<a href="https://twitter.com/hashtag/Unity?src=hash&amp;ref_src=twsrc%5Etfw">#Unity</a> <a href="https://t.co/aNp2CUWJHe">pic.twitter.com/aNp2CUWJHe</a></p>&mdash; foka (@foka22ok) <a href="https://twitter.com/foka22ok/status/1207998103715905538?ref_src=twsrc%5Etfw">December 20, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

<blockquote class="twitter-tweet" data-conversation="none" data-theme="light"><p lang="ja" dir="ltr">こうする<a href="https://twitter.com/hashtag/Unity?src=hash&amp;ref_src=twsrc%5Etfw">#Unity</a> <a href="https://t.co/EbXXXA87Qm">pic.twitter.com/EbXXXA87Qm</a></p>&mdash; foka (@foka22ok) <a href="https://twitter.com/foka22ok/status/1207998156727701504?ref_src=twsrc%5Etfw">December 20, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

## SPOUT
Unityにはアプリケーション間の映像転送の仕組みはありませんが、それを可能にする技術の一つとして`SPOUT`があります。
SPOUTは、同一PC内のアプリ間で高速映像共有を可能にするスグレモノ。
（Windows用。Macには同等技術にSyphonというのがあります）

`SPOUT`
http://spout.zeal.co/

SPOUTをこんな風に組み合わせることで、プロジェクションのVR確認ができるようになります。
![UnityVR_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16457/8ef9e44f-4dee-86ff-d62f-82bbb3fdcc3a.png)

### KlakSpout
UnityでSPOUTを使う場合ですが、高橋啓治郎氏が`KlakSpout`というUnity用Spoutプラグインを作られているので、これをありがたく使わせてもらいます。
https://github.com/keijiro/KlakSpout

### SPOUT送信
使い方は簡単で、プロジェクション側のプロジェクトのカメラに`SpoutSender`をくっつけるだけで送信します。
![2019-12-20_15h47_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16457/6858b224-7b35-0e1f-0361-5dd9e9a3578e.png)
GameObjectの名前（↑では`ProjectionCamera`）が重要で、この名前で映像送信されます。

なお、カメラ映像だけでなくRenderTextureに映した映像も送れるので、用途に応じて使い分けると良いです。


### SPOUT受信
VR側に空のGameObjectでも作って、そこに`SpoutReciever`をくっつけます。
![2019-12-20_18h07_59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16457/23085086-f8f0-cb95-c1dc-142c40386e99.png)
`SourceName`が送信元の映像名になります。
送信元と一致している必要があるので、間違えずに入力するか、`Select`でプルダウンから選択して下さい。

受け取った映像をRenderTextureに映す場合は`TargetTexture`を、Rendererに映す場合は`TargetRenderer`を指定します。

# PCも分離して処理負荷も分離する

![doshite_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16457/89e817d8-4f64-0a84-05d4-e0162dfe0d53.png)
そんな場合でも大丈夫。
SPOUTの代わりに、同一ネットワーク内のPC間の高速映像転送が行えるNDI（Network Device Interface）を使うと、プロジェクション用のPCとVR用のPCを分けることができます。

`NDI（Network Device Interface）`
https://www.ndi.tv/

NDIを組み合わせるとこんな感じ。
![UnityVR_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16457/c9f13efc-ea33-e47e-59cd-f78c3b6c4a67.png)


### KlakNDI
UnityでNDIを使う場合ですが、同じく高橋啓治郎氏が`KlakNDI`というUnity用NDIプラグインを作られているので、これも大変ありがたく使わせてもらいます。
https://github.com/keijiro/KlakNDI

（使い方はKlackSpoutとほぼ同じなので省略）

# センシングも確認したい

![doshite_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16457/6e4af376-671a-63b3-36e8-9e2149c38032.png)
場所を使ったコンテンツでは測域センサーを使うなど、センサー利用のコンテンツも多いですね。
そんな場合でも現場同様につなぐことができます。
![UnityVR_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16457/577f4110-99be-39c0-4c94-fd86f445a0f6.png)

# 複数人でも確認する

![doshite_4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16457/c2925381-6bc5-62b0-15f2-e3b7f9838dce.png)
そんな場合はこうです。
NDIは一つのSenderを複数のRecieverで受け取ることができます。
![UnityVR_4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16457/cccdaefc-9251-4aa7-9d86-029ea939ce76.png)

# Unity以外との連携
![doshite_5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16457/fbf3de56-0783-2c99-f40a-2badb7e4cdc8.png)

そんな場合も、SPOUT・NDIのどちらかに対応していれば大丈夫です。
例えばTouchDesignerを使っていた場合はこんな感じ。
![UnityVR_5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16457/09b6612b-19c5-55d4-78ae-9a2dc32cf716.png)

# SPOUTとNDIの連携
![doshite_6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16457/fdc6da42-a7e0-9f28-e78b-e38f90b85f89.png)
これも方法があります。
SPOUTとNDIは組み合わせることができます。

ありがたいことに、SPOUTが公式に`SPOUT to NDI`と`NDI to SPOUT`を用意しています。

これらを使うと、
`SPOUT送信`　→　`SPOUT to NDI`　→　(NDIで別PCに映像転送)　→　`NDI to SPOUT`　→　`SPOUT受信`
ということもできます。

これでSPOUTが使えるけどNDIが使えないアプリケーションでも、複数PCアプリケーション間の映像転送ができるようになります（TouchDesignerのNON-COMMERCIAL版とか、Pythonアプリケーションとか）。
http://spout.zeal.co/download-spout-to-ndi/

`SPOUT to NDI`・`NDI to SPOUT`の使い方は下記記事で紹介されていたので、ここでは割愛します。
[Touch Designer 有料版を使わずにSPOUT&NDIで映像共有](https://qiita.com/n_bando/items/3176cf4664fe76f0b333)

# まとめ
場所を使ったコンテンツの場合、その場所ならではのサイズ感、見え感や体験感はとても重要になります。
それをVRを使って確認、関係者と共有しておくと、いざ現場に赴いた時に大変スムーズに進めることができるようになります。

現場が掴み切れなくて不安な点があったら、ぜひVRでご確認を。
![genbacat.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16457/b1701d44-8998-cd6c-0dce-dd4b817a408a.jpeg)