Upgrade to Pro — share decks privately, control downloads, hide ads and more …

ARでVRアバターを表示するシステムを構築しよう

 ARでVRアバターを表示するシステムを構築しよう

次の講演資料です。
・どっかんナゴヤ'18 Jun. https://dcn.connpass.com/event/87240/
・ABC 2018 Spring https://abc.android-group.jp/2018s/

プロジェクトファイル
https://github.com/TORISOUP/AR_VR_Viewer

torisoup

June 09, 2018
Tweet

More Decks by torisoup

Other Decks in Technology

Transcript

  1. ARでVRアバターを
    表示するシステムを
    構築しよう
    2018/06/09
    とりすーぷ

    View full-size slide

  2. 自己紹介
    • とりすーぷ
    • @toRisouP
    • 個人ゲーム開発者
    • 日本Androidの会Unity部 部員のはず

    View full-size slide

  3. 過去作
    • ハクレイフリーマーケット
    • Unity製、PC向け東方2次創作ゲーム、ネットワーク対戦対応
    • 発売中!

    View full-size slide

  4. 今回の発表概要

    View full-size slide

  5. こういうものを作ってみた
    相手:みゅみゅ(@miyumiyuna5)さん
    https://twitter.com/toRisouP/status/996761692456435712

    View full-size slide

  6. これなに?
    • VR空間のアバターをARで表示するシステム
    • スマホだけでVR空間をそれっぽく見たい
    • VR側での演者の動きをそのままARで表示する
    • 通話機能で会話できる
    • ARカメラの位置をVR側から視認できる

    View full-size slide

  7. できること
    • VR側
    • アバターの操作
    • 表情変更
    • AR側カメラがどこにあるかを知る
    • AR側
    • マーカーレスで認識した平面にアバターを配置
    • アバターのサイズ変更

    View full-size slide

  8. コンセプト
    • 「次世代のVR生放送がこんな感じになるといいな」
    • VR空間をスマホさえあれば見られるようにしたい
    • AR側からVR側へのインタラクションもできるといいな
    • 簡略化のために1対1の通信で作るが、最終的には多対多にしたい

    View full-size slide

  9. つまり?
    • こういう美少女空間をスマホARでみたい
    画像引用:https://www.infiniteloop.co.jp/blog/2018/04/virtualcast-release/

    View full-size slide

  10. Unityプロジェクト
    • githubで公開済み
    • https://github.com/TORISOUP/AR_VR_Viewer
    • CC0 で公開

    View full-size slide

  11. 今回の発表内容
    • どうやって作ったか?のノウハウ共有
    • 構成
    • ワークフロー
    • VRMの使い方
    • ネットワーク同期の話
    • VR/ARの実装
    • その他実装のコツ

    View full-size slide

  12. 全体図
    VR側 AR側
    ・コントローラ入力
    ・アバターの姿勢・座標
    ・音声
    ・ARカメラの位置
    ・音声

    View full-size slide

  13. プロジェクト構成
    • 1つのプロジェクトでAR/VRの両方をビルドする
    • 同じプロジェクトから両パターンビルドできるようにする
    • 単にプロジェクトを分けるのが面倒くさかっただけ…

    View full-size slide

  14. 使ったもの(機材)
    • VR側
    • Windows PC
    • HTC Vive
    • AR側
    • Galaxy S8

    View full-size slide

  15. 使ったもの(ソフト)
    • Unity 2018.1 / .NET 4.6 / C#6.0
    • VRM / UniVRM
    • ARCore
    • SteamVR、Final IK
    • Photon Cloud, Photon Voice
    • UniRx, PhotonRx
    • Zenject

    View full-size slide

  16. Unity 2018.1
    • .NET 4.6 /C#6.0の開発がどれくらい楽か検証したいので採用
    • async/awaitを使いたい

    View full-size slide

  17. VRM
    • VRアプリケーション向け人型3Dアバターフォーマット
    • オープンソースで様々なプラットフォームで利用可能
    • 利用ライセンスをファイル自体に埋め込める
    • 今回はVRMのUnity向けインポータ「UniVRM」も使用

    View full-size slide

  18. ARCore
    • Google製のARライブラリ
    • Tangoの後継
    • マーカ検知、マーカレストラッキング、床・壁の検知、光源推測、特
    徴点抽出、認識した空間の共有
    • 利用可能端末がかなり少ない(アップデートで追加はされている)
    • 今回の利用バージョンは1.2.0

    View full-size slide

  19. SteamVR
    • Valve社が提供するVRプラットフォーム & SDK
    • PC向けVR開発に利用可能なSDK

    View full-size slide

  20. Photon Cloud/Voice
    • Photon Cloud
    • ドイツのExit Games社製の通信フレームワーク&クラウドサーバ
    • 20人同時接続までなら無料で利用可能
    • Unity向けSDK(PUN)を利用して開発する
    • Photon Voice
    • Photon Cloudと連動して音声通信機能を追加するサービス

    View full-size slide

  21. その他
    • UniRx
    • Reactive Exntensions for Unity
    • イベント処理、非同期処理の整備に使った
    • Zenject
    • 依存性注入(DI)のフレームワーク
    • コンポーネントの参照解決に使った

    View full-size slide

  22. 開発方針
    • 「モダンな開発をしたい」
    • .NET 4.6 + C# 6.0 で開発
    • 全体的に挙動を非同期にする(Task, Observable, async/awaitの活用)
    • DIをメインに使った開発
    • static変数を使った参照解決をしない
    • GameObject.Find禁止

    View full-size slide

  23. ワークフローの話

    View full-size slide

  24. といっても大したことはしていない
    • 個人開発なので大したワークフローは無い
    • どういう順番で作ったかの話

    View full-size slide

  25. 製作期間
    • 4日(約30時間)
    • 土日全部と、平日の夜中

    View full-size slide

  26. 制作の流れ
    1. 通信デバッグ用のビルドを作成
    2. VR/AR対応前の状態で動作確認
    3. ARCoreを使った実装(InstantPreview)
    4. Android実機確認
    5. VR実装
    6. 結合して動作確認

    View full-size slide

  27. 実機確認はツライ
    • 機材トラブルで時間を取られる
    • ビルドが遅い
    • 物理的に機材を使う手間がしんどい
    • できるだけ実機確認を後回しにする
    • もちろん、技術検証だけは先にやっておく

    View full-size slide

  28. VRとARを同時にデバッグするのは無理
    • VR側の動作確認には、Viveを装着する必要がある
    • AR側の動作確認には、スマホを持って移動する必要がある
    • 1人じゃ無理!!!!!!

    View full-size slide

  29. デバッグ用のビルドファイル
    • アバターがアニメーションを自動再生するだけのビルド
    • VR側のモック化として利用
    • 通信機能だけ実装しておき、モーションデータを送信する
    @UTJ/UCL

    View full-size slide

  30. シンプルなプロジェクトで先に作る
    • AR、VRは無視して単体で作れるところまで作る
    • モック化等の小技を駆使してデバッグをする
    送信 受信
    https://twitter.com/toRisouP/status/995230604928036864

    View full-size slide

  31. ARCoreを導入して実験
    • Instant Preview機能が便利
    • USB接続されたスマホを使ってUnityEditor上でデバッグできる
    ←先程のデバッグ用ビルド
    https://twitter.com/toRisouP/status/995640657195581440

    View full-size slide

  32. VR側を実装
    • SteamVRを導入して実装
    • 詳しくは後述

    View full-size slide

  33. あとは最終確認
    • VR側役をやってくれる友人を用意
    • 時間を合わせて起動して動作確認する
    https://twitter.com/toRisouP/status/996763932328058881

    View full-size slide

  34. 「ワークフロー」のまとめ
    • コア部分は先に作っておくと楽
    • AR実装、VR実装、それぞれで共通して動かせる部分を先に作る
    • AR/VRの状態をモック化できるようになってるとなお良い
    • ARとVRはプロジェクトを分けるべきだった
    • Switch Platformがツライ

    View full-size slide

  35. VRMの使い方

    View full-size slide

  36. VRMとは
    • VRアプリケーション向け人型3Dアバターフォーマット
    • https://dwango.github.io/vrm/

    View full-size slide

  37. VRMファイルを探すには
    • ニコニ立体で探すのが良い
    • 利用許可なライセンスのモデルを探して利用
    • 今回はニコニ立体ちゃんを使用
    https://3d.nicovideo.jp/works/td32797

    View full-size slide

  38. Unityで使うためには
    • UniVRMを導入する必要がある
    • githubから導入すればOK
    • https://github.com/dwango/UniVRM
    • バージョンアップが頻繁
    • (まだ安定している感じはしない)

    View full-size slide

  39. Unity上でのVRMの取り扱い方
    • 2パターンある
    • Prefab化する方法
    • 動的にロードする方法

    View full-size slide

  40. Prefab化する方法
    • vrm拡張子のファイルは自動的にロードされてPrefab化される
    • ビルドファイルにモデルを埋め込むならこの手法が楽
    • あとからユーザがモデルを差し替えるみたいなことはできない手法

    View full-size slide

  41. 動的ロードする方法
    • ランタイムロードしてモデルを生成する
    • 後から自由にモデルを変更できるようにするならこっち
    • VRMの使い方として、おそらくこの方法がメイン
    • 今回はこちらの方法でやる
    直接ファイルパスを指定してロードする場合

    View full-size slide

  42. おすすめのロード方法
    • WWWで先にロードしてからVRMImporterに渡すのがおすすめ
    • VRMImporterのデフォルトはなぜか同期読み込み
    • Android実機ではWWWじゃないとロードできないディレクトリがある
    UniRxを導入しているとWWWもawaitできる
    https://github.com/TORISOUP/AR_VR_Viewer/blob/master/Assets/VrmArPlayer/
    Scripts/Scene/Main/Common/AvaterProvider.cs

    View full-size slide

  43. 動的ロードしたVRMはどうなるのか
    • コンポーネントがアタッチされたGameObjectが生成される

    View full-size slide

  44. 最初からアタッチされてるコンポーネント
    ←メタ情報が格納されたコンポーネント
    ←身体の構造の設定値が格納されたコンポーネント
    ←表情を制御するコンポーネント
    ←HMDを配置するときに使うコンポーネント
    ←視線制御に使うコンポーネント
    ←同上

    View full-size slide

  45. オリジナルの制御を加える場合は
    • AddComponentで自作コンポーネントを設定する
    • 同時に初期パラメータもこのタイミングで設定する
    • 初期化完了のタイミングを通知する機構を用意すると便利
    指の曲げ制御コンポーネント
    https://github.com/TORISOUP/AR_VR_Viewer/blob/master/Assets/VrmArPlayer/
    Scripts/Scene/Main/Common/AvaterController.cs#L46

    View full-size slide

  46. 動的ロードは結構めんどうくさい
    • 初期化を非同期にしていかないといけない
    • VRMの読み込みにまず数秒かかる
    • スクリプトからコンポーネントの初期化が必要になる
    • AddComponentしたコンポーネントを手動で初期化する必要がある
    • 他のコンポーネントに依存する場合はその参照解決が必要

    View full-size slide

  47. VRMアバターの制御

    View full-size slide

  48. 今回組み込んだ機能は3つ
    • 表情の操作
    • 指の曲げ伸ばし操作
    • リップシンク

    View full-size slide

  49. 表情
    • Viveコントローラのタッチパッドで表情を変更する




    View full-size slide

  50. 表情の変え方
    • VRMBlendShapeProxyコンポーネントを使えばOK
    ←これ

    View full-size slide

  51. コントローラ操作で表情変更
    • VRMBlendShapeProxy.SetValue()を使って設定する
    • 0 – 1の範囲で指定
    タッチパッドを触った座標(2次元ベクトル)と設定された表情のベクトルとの内積をとった値を使う
    https://github.com/TORISOUP/AR_VR_Viewer/blob/master/Assets/VrmArPlayer/
    Scripts/Scene/Main/Common/AvaterController.cs#L137-L140

    View full-size slide

  52. 表情変更:ポイント1
    • 表情を合成する場合はSetValue()の第三引数にfalseを指定
    • trueの場合はその時の値で強制上書きになる
    • falseを指定した場合はApply()を呼び出すと合成値が反映される
    このタイミング(Update()内)ではすべてfalseにしておく
    LateUpdate()のタイミングでApply()

    View full-size slide

  53. 表情変更:ポイント2
    • Lerp(線形補間)を入れると柔らかくなる
    Lerpなし Lerpあり
    https://twitter.com/toRisouP/status/995322292346306560

    View full-size slide

  54. 指の曲げ伸ばし
    • VRMにデフォルトでは用意されていない
    • スクリプトを自分で用意する必要がある
    • FingerControllerコンポーネント
    (みゅみゅさん作のスクリプトを許可をもらって改変・配布)
    • これを動的にアタッチして使う
    https://github.com/TORISOUP/AR_VR_Viewer/blob/master/Assets/VrmArPlayer/
    Scripts/Scene/Main/Common/FingerController.cs

    View full-size slide

  55. コントローラ操作で指の曲げ伸ばし
    • 各コントローラのトリガーキーの入力を反映
    • 曲げる/伸ばす の2段階のみ
    https://github.com/TORISOUP/AR_VR_Viewer/blob/master/Assets/VrmArPlayer/
    Scripts/Scene/Main/Common/AvaterController.cs#L44

    View full-size slide

  56. 手の曲げ伸ばし:ポイント
    • 2段階しかなくてもLerpを入れればなめらかになる
    https://twitter.com/toRisouP/status/995312888070860801

    View full-size slide

  57. リップシンク
    • 音声に合わせて口パクする機能
    • 今回は Oculus Lipsync Unity を使った
    • https://developer.oculus.com/downloads/package/oculus-lipsync-
    unity/

    View full-size slide

  58. リップシンク設定
    • 音声の解析結果をそのままBlendShapeに反映すればOK
    • OVRLipSyncContextコンポーネントが解析結果を保持している
    https://github.com/TORISOUP/AR_VR_Viewer/blob/master/Assets/VrmArPlayer/
    Scripts/Scene/Main/Common/AvaterController.cs#L81-L93

    View full-size slide

  59. VRM まとめ
    • アバター制御の基本的な機能が揃っており便利
    • Humanoidの制御に必要なことは最低限はできそう
    • 「動的ロード」はちょっと難しめ
    • プログラムが書けないとキビシイ
    • まだ出て間もないのでドキュメント不足気味

    View full-size slide

  60. ネットワーク同期の話

    View full-size slide

  61. ネットワーク同期する情報
    • アバターの姿勢
    • 頭、腰、手先、足先の座標と角度
    • コントローラ入力値(表情・手の曲げ伸ばしに使用)
    • タッチパッドの座標とトリガーキーの状態
    • ARカメラの座標
    • VR空間内にARカメラがどこにあるかを表示するため

    View full-size slide

  62. ネットワーク同期のやり方
    • PUN (Photon Unity Networking) の機能をそのまま使うだけ
    https://github.com/TORISOUP/AR_VR_Viewer/blob/master/Assets/VrmArPlayer/
    Scripts/Scene/Main/Common/AvaterSynchronizer.cs#L90-L134

    View full-size slide

  63. ハマりどころ
    • VRMの動的ロードとPhoton Cloudの相性が悪い
    • Photon Cloudの同期の仕組みに乗せるにはPrefab化が必要
    • VRMの動的ロードを使っているとPrefabが用意できない
    • VRMのアバターを直接同期する仕組みにすることができない

    View full-size slide

  64. 図解
    VRMの動的ロードを使うと同期ができない
    (PhotonViewはAddComponentできないため)
    アバター アバター
    通信

    View full-size slide

  65. 解決策
    • 「同期管理オブジェクト」と「アバター」を分離して作る
    • アバターを独立したGameObjectとして生成する
    • アバターが生成されたら同期管理オブジェクトに登録する
    • 同期管理オブジェクトがアバターの情報を同期する

    View full-size slide

  66. 図解
    同期オブジェクトを仲介させることで、
    データの同期を実現する
    アバター アバター
    通信
    同期オブジェクト 同期オブジェクト
    姿勢書き込み 姿勢反映

    View full-size slide

  67. アバター生成時に同期登録
    アバター生成完了イベントが来たら
    同期管理オブジェクトへ登録する
    https://github.com/TORISOUP/AR_VR_Viewer/blob/master/Assets/VrmArPlayer/
    Scripts/Scene/Main/Common/AvaterScynchronizeDispatcher.cs#L51

    View full-size slide

  68. 同期オブジェクトの様子
    • 白い箱が可視化した同期用オブジェクト

    View full-size slide

  69. コツ
    • 受信側で姿勢の再現時にもLerpを入れるといい感じ
    • 補間が入って動きがなめらかになる
    https://twitter.com/toRisouP/status/995579063405195264

    View full-size slide

  70. 設定ミスするとこんな感じになる
    • 同期の設定ミスったときのやつ
    https://twitter.com/toRisouP/status/995565615405387776

    View full-size slide

  71. ネットワーク同期 まとめ
    • Photon Cloudを使えばクライアント実装のみで完結する
    • VRMの動的ロードと合わせるには工夫が必要
    • 同時接続数は1部屋あたり10人くらいが限界そう
    • Photon Cloudの制約(メッセージ数上限)
    • デモ用途なら十分
    • 不特定多数への生放送に用いるには専用のインフラ構築が必要

    View full-size slide

  72. VR側の実装の話

    View full-size slide

  73. Steam VRを導入
    • Asset Storeから導入する

    View full-size slide

  74. IK
    • 終端を指定し、そこに向かって関節を制御する機能
    • Inverse Kinematics(逆運動学)

    View full-size slide

  75. IKの対象にVRコントローラを指定
    • HMDやコントローラの座標をIKに使うことで、アバターが
    操作できるようになる
    • 今回はFinal IKに同梱されているVRIKコンポーネントを利用した

    View full-size slide

  76. Final IK
    • Unity向けのIKアセット
    • VR対応

    View full-size slide

  77. 実装
    VRのときはコントローラのTransformをIKのターゲットにする
    ARのときは同期オブジェクトをIKのターゲットにする
    https://github.com/TORISOUP/AR_VR_Viewer/blob/master/Assets/VrmArPlayer/
    Scripts/Scene/Main/Common/AvaterScynchronizeDispatcher.cs#L81-L94

    View full-size slide

  78. VR実装 まとめ
    • vtuberを実装する方法をそのまま行うだけ
    • ググったら情報いっぱい出てくる
    • VRで「結月ゆかり」になって生放送する
    https://qiita.com/toRisouP/items/14fe62f89808013f9f6e

    View full-size slide

  79. AR実装の話

    View full-size slide

  80. ARCore SDKを導入
    • Githubからダウンロード
    • https://github.com/google-ar/arcore-unity-sdk/releases/tag/v1.2.0

    View full-size slide

  81. Instant Preview
    • USBで繋いだスマホを使って直接デバッグできる
    • Unity Editorで実行ボタンを押すだけ

    View full-size slide

  82. サンプルコードをそのまま流用
    • HelloAR
    • 平面を認識してタップした位置にドロイド君を表示するサンプル
    • これを流用し、タップ地点の座標を取り出せるようにした

    View full-size slide

  83. 実装
    • ArViewManager
    https://github.com/TORISOUP/AR_VR_Viewer/blob/master/Assets/VrmArPlayer/
    Scripts/Scene/Main/ForSmartphone/AR/ArViewManager.cs#L107-L114

    View full-size slide

  84. タップ位置を基準座標にする
    • アバターの親Transformの座標をタップ位置に設定
    https://github.com/TORISOUP/AR_VR_Viewer/blob/master/Assets/VrmArPlayer/
    Scripts/Scene/Main/ForSmartphone/StageController.cs#L56

    View full-size slide

  85. タップした位置にアバターを表示

    View full-size slide

  86. アバターの表示サイズの変更
    • uGUIのスライダーをいじるとアバターのサイズが変わる
    • TransformのScaleを直接変更している
    • 小さくしすぎると足のIKがおかしくなる

    View full-size slide

  87. IKが壊れる理由
    • IKの設定値の調整不足
    • アバターのサイズが変わったらIKの設定も同時に変更する必要がある
    (歩幅、股の開き具合など)
    • 単にこの調整機能を入れ忘れていただけ…

    View full-size slide

  88. Androidビルドして実機確認
    • 動かすとだいたい最初は上手くいかない

    View full-size slide

  89. 動かなかった理由
    • パーミッションが足りない
    • マイクが不許可になってた
    • カメラの認可ダイアログは出たのに、マイクは出なかった
    • モデルデータがロードできない
    • StreamingAssetsはWWWでしかロードできない問題と衝突
    • UniVRMをそのまま使うとFile.ReadAllBytesでVRMをロードしようとする

    View full-size slide

  90. Androidビルドでデバッグするときは
    • Android Device Monitorが使える
    • Android SDKについてくるログ閲覧ツール
    • ビルド時にDevelopment BuildにするとDebug.Logがここに流れる

    View full-size slide

  91. 問題発生:Windowsビルドが通らない!
    • ARCoreを導入するとWindowsビルドが通らない
    • スタンドアローンビルド向けのdllが用意されていないから

    View full-size slide

  92. 回避策
    • Android向けdllを無理矢理よみこませてビルドする
    • かなりバッドノウハウ
    • やはりARとVRでプロジェクトを分けたほうが良さそう…
    これを追加して無理矢理よみこませる

    View full-size slide

  93. AR実装 まとめ
    • ARCoreのサンプルコードをそのまま使っただけ
    • ARCoreの自体の機能はほとんど活かせてない
    • VRプロジェクトとの混在は避けたほうが良さそう
    • ビルドは無理矢理通るようになったけど、
    今度はInstant Previewがおかしくなった

    View full-size slide

  94. その他実装のコツ

    View full-size slide

  95. その1:処理の非同期化
    • アバター読み込み、ネットワーク通信などで非同期処理が多い
    • async/await & UniRx が大活躍

    View full-size slide

  96. UniRx
    • Reactive Exntensions for Unity
    • 非同期処理、イベント処理に強くなるライブラリ
    • Asset Storeから導入可能(無料)
    • MITライセンス

    View full-size slide

  97. 愚直に書くと…
    • Actionコールバックだらけ
    • コルーチンもなんとかしたい

    View full-size slide

  98. async/await + UniRx
    • コルーチンを使わずにWWWをawaitで待てる
    • VRMのロードもawaitで待てる

    View full-size slide

  99. Photonの初期化周りの処理
    • PhotonRxを導入するとPUNのメソッドをTask化できる
    • https://github.com/TORISOUP/PhotonRx

    View full-size slide

  100. PhotonRx + Task + UniRx
    • ボタンが押されたらログイン→処理が終わるまでボタン無効化
    https://github.com/TORISOUP/AR_VR_Viewer/blob/master/Assets/VrmArPlayer/
    Scripts/Scene/Title/LoginPresenter.cs

    View full-size slide

  101. AsyncReactiveCommand
    • 説明ややこしいのでQiitaみて
    • 【UniRx】ReactiveCommand/AsyncReactiveCommandについて
    • https://qiita.com/toRisouP/items/c6fba9f01e6d15dabd79

    View full-size slide

  102. その2:設計の話
    • どのモードで動いているか意識せずに作りたい
    • いまARなのか、VRなのかをできるだけ意識せずにコードを書きたい
    • オープン・クローズド原則を守りたい

    View full-size slide

  103. どういうこと?
    • たとえば「コントローラ入力」
    • VR時:Viveコントローラの入力を使う
    • AR時:ネットワーク通信で送られてきた値を使う
    • デバッグ時:キーボードの入力を使いたい
    • これをif文で書き分けるみたいなことはしたくない
    • DIで乗り切ろう

    View full-size slide

  104. DI(依存性注入)
    • 抽象化した場所に、具象クラスを後から指定する
    • クラスを差し替えるだけで挙動を後から変更できるようになる

    View full-size slide

  105. Zenject
    • Unity向けのDIのフレームワーク
    • DIするならこれが便利
    • Asset Storeから導入可能(無料)
    • MITライセンス

    View full-size slide

  106. 抽象化
    • 入力イベントを発行するインタフェースを定義
    • UniRxのReactiveProperty化が便利
    https://github.com/TORISOUP/AR_VR_Viewer/blob/master/Assets/VrmArPlayer/
    Scripts/Scene/Main/Common/Inputs/IInputEventProvider.cs

    View full-size slide

  107. 利用時はこのインタフェースのみを触る
    • 実体がどのクラスであるかは無視して書く
    • 使うときはインタフェースしか意識しない

    View full-size slide

  108. Installer(Zenject)
    • どのインタフェースにどの実装を使うかを定義する機能
    • このインタフェースにはこのクラスを使う、みたいなのを書く場所
    読み方
    IInputEventProviderおよびIInputSetableが要求された場合は、
    VrInputEventProviderを注入する(その際は同じインスタンスを使い回す)

    View full-size slide

  109. Installerをシーンごとにわけて用意する
    • VRモード、ARモードのシーンでそれぞれ中身を変える
    • VRのときはVR用InputEventProvider
    • ARのときはネットワーク同期用InputEventProvider
    VRモードのときのInstaller ARモードのときのInstaller
    https://github.com/TORISOUP/AR_VR_Viewer/blob/master/Assets/VrmArPlayer/
    Scripts/Scene/Main/ForPC/ForPCInstaller.cs
    https://github.com/TORISOUP/AR_VR_Viewer/blob/master/Assets/VrmArPlayer/
    Scripts/Scene/Main/ForSmartphone/ForSmartphoneInstaller.cs

    View full-size slide

  110. SceneにそのInstallerを配置する
    • シーンを切り替えると自動的にDIする実装が切り替わる
    VR用のシーンで使うInstaller

    View full-size slide

  111. 後はそのまま実行すれば終わり
    • 設定に応じて自動的に実装が注入される
    • SceneLoad時に自動的に注入されていく

    View full-size slide

  112. DIはムズカシイ
    • 疎結合な設計ができてないと効果がない
    • オープン・クローズド原則
    • 依存関係逆転の原則

    View full-size slide

  113. 設計の勉強をするには
    • この資料を見て
    • Unity開発で使える設計の話+Zenjectの紹介
    • https://www.slideshare.net/torisoup/unityzenject

    View full-size slide

  114. Zenjectを使う上での注意点
    • DIの実行にはオブジェクトの存在をZenjectに認識させる必要
    がある
    • 直接Instantiateしたり、AddComponentするとDIされない
    • あらかじめSceneに配置しておくか、Zenjectのコンテナ経由で
    GameObjectを作る/AddComponentを実行する必要がある

    View full-size slide

  115. Photonと相性が悪い
    • Photon.Instantiateで生成したオブジェクトはZenjectが
    検知できない
    • Photon経由で作ったオブジェクトはDIが実行されない

    View full-size slide

  116. 解決策
    • ZenAutoInjecterコンポーネントをアタッチする
    • これを対象につけておくとオブジェクト生成後にZenjectに認識される
    • 後追いでDIが実行されるようになる

    View full-size slide

  117. ZenAutoInjectorを使う上での注意
    • DIのタイミングがいつになるかわからない
    • Start()の実行までにDIが実行されないことがある
    • DIが終わったことを検知して処理を開始する仕組みにしよう

    View full-size slide

  118. DIの実行を検知する方法
    • メソッドインジェクションを使う
    • DIが実行されたタイミングでメソッドが実行される
    • その中でフラグを立てるなり、イベント飛ばすなりすればよい
    https://github.com/TORISOUP/AR_VR_Viewer/blob/master/Assets/VrmArPlayer/
    Scripts/Scene/Main/Common/SynchronizeCamera.cs#L30-L42

    View full-size slide

  119. その他実装のコツ まとめ
    • 非同期処理は対処法を知っておくべし
    • async/await, Task, UniRxの使い方を覚えておくと良さげ
    • Zenjectを使ったDIが非常に便利
    • 無駄なif文/switch文を減らせる
    • わざわざマネージャクラスをシングルトン化する必要がなくなる
    • デバッグやテストがやりやすくなる

    View full-size slide

  120. さいごに

    View full-size slide

  121. 今回作ってみた感想
    • VRとARとネットワーク同期といろいろ盛りすぎた
    • やってることに対して作るのがめっちゃしんどい
    • でも未来は感じる
    • プログラマ的には楽しかった
    • 非同期処理の多用&DIの多用
    • キレイにDIがハマると嬉しい

    View full-size slide

  122. 現状の問題点
    • 技術デモの領域を出ない設計になってる
    • VR1人-AR1人、の1対1通信を想定した作りになってる
    • VR複数-AR複数、の多対多は現状の設計じゃ無理
    • スケール性がない
    • まともにサービス化するなら通信サーバの開発、インフラ構築が必要
    • 個人開発じゃ技術デモくらいが限界

    View full-size slide

  123. さいごにまとめ
    • VR空間をARで可視化するのは夢がある
    • AR/MRデバイスがもうちょっと普及してくれたらありがたい
    • VRMが便利でオススメ
    • 簡単に人型アバターを動的ロードして扱えて良さげ
    • 今後の3Dコンテンツの主流フォーマットになってほしいな

    View full-size slide