Link
Embed
Share
Beginning
This slide
Copy link URL
Copy link URL
Copy iframe embed code
Copy iframe embed code
Copy javascript embed code
Copy javascript embed code
Share
Tweet
Share
Tweet
Slide 1
Slide 1 text
ARでVRアバターを 表示するシステムを 構築しよう 2018/06/09 とりすーぷ
Slide 2
Slide 2 text
自己紹介 • とりすーぷ • @toRisouP • 個人ゲーム開発者 • 日本Androidの会Unity部 部員のはず
Slide 3
Slide 3 text
過去作 • ハクレイフリーマーケット • Unity製、PC向け東方2次創作ゲーム、ネットワーク対戦対応 • 発売中!
Slide 4
Slide 4 text
今回の発表概要
Slide 5
Slide 5 text
こういうものを作ってみた 相手:みゅみゅ(@miyumiyuna5)さん https://twitter.com/toRisouP/status/996761692456435712
Slide 6
Slide 6 text
これなに? • VR空間のアバターをARで表示するシステム • スマホだけでVR空間をそれっぽく見たい • VR側での演者の動きをそのままARで表示する • 通話機能で会話できる • ARカメラの位置をVR側から視認できる
Slide 7
Slide 7 text
できること • VR側 • アバターの操作 • 表情変更 • AR側カメラがどこにあるかを知る • AR側 • マーカーレスで認識した平面にアバターを配置 • アバターのサイズ変更
Slide 8
Slide 8 text
コンセプト • 「次世代のVR生放送がこんな感じになるといいな」 • VR空間をスマホさえあれば見られるようにしたい • AR側からVR側へのインタラクションもできるといいな • 簡略化のために1対1の通信で作るが、最終的には多対多にしたい
Slide 9
Slide 9 text
つまり? • こういう美少女空間をスマホARでみたい 画像引用:https://www.infiniteloop.co.jp/blog/2018/04/virtualcast-release/
Slide 10
Slide 10 text
Unityプロジェクト • githubで公開済み • https://github.com/TORISOUP/AR_VR_Viewer • CC0 で公開
Slide 11
Slide 11 text
今回の発表内容 • どうやって作ったか?のノウハウ共有 • 構成 • ワークフロー • VRMの使い方 • ネットワーク同期の話 • VR/ARの実装 • その他実装のコツ
Slide 12
Slide 12 text
構成
Slide 13
Slide 13 text
全体図 VR側 AR側 ・コントローラ入力 ・アバターの姿勢・座標 ・音声 ・ARカメラの位置 ・音声
Slide 14
Slide 14 text
プロジェクト構成 • 1つのプロジェクトでAR/VRの両方をビルドする • 同じプロジェクトから両パターンビルドできるようにする • 単にプロジェクトを分けるのが面倒くさかっただけ…
Slide 15
Slide 15 text
使ったもの(機材) • VR側 • Windows PC • HTC Vive • AR側 • Galaxy S8
Slide 16
Slide 16 text
使ったもの(ソフト) • Unity 2018.1 / .NET 4.6 / C#6.0 • VRM / UniVRM • ARCore • SteamVR、Final IK • Photon Cloud, Photon Voice • UniRx, PhotonRx • Zenject
Slide 17
Slide 17 text
Unity 2018.1 • .NET 4.6 /C#6.0の開発がどれくらい楽か検証したいので採用 • async/awaitを使いたい
Slide 18
Slide 18 text
VRM • VRアプリケーション向け人型3Dアバターフォーマット • オープンソースで様々なプラットフォームで利用可能 • 利用ライセンスをファイル自体に埋め込める • 今回はVRMのUnity向けインポータ「UniVRM」も使用
Slide 19
Slide 19 text
ARCore • Google製のARライブラリ • Tangoの後継 • マーカ検知、マーカレストラッキング、床・壁の検知、光源推測、特 徴点抽出、認識した空間の共有 • 利用可能端末がかなり少ない(アップデートで追加はされている) • 今回の利用バージョンは1.2.0
Slide 20
Slide 20 text
SteamVR • Valve社が提供するVRプラットフォーム & SDK • PC向けVR開発に利用可能なSDK
Slide 21
Slide 21 text
Photon Cloud/Voice • Photon Cloud • ドイツのExit Games社製の通信フレームワーク&クラウドサーバ • 20人同時接続までなら無料で利用可能 • Unity向けSDK(PUN)を利用して開発する • Photon Voice • Photon Cloudと連動して音声通信機能を追加するサービス
Slide 22
Slide 22 text
その他 • UniRx • Reactive Exntensions for Unity • イベント処理、非同期処理の整備に使った • Zenject • 依存性注入(DI)のフレームワーク • コンポーネントの参照解決に使った
Slide 23
Slide 23 text
開発方針 • 「モダンな開発をしたい」 • .NET 4.6 + C# 6.0 で開発 • 全体的に挙動を非同期にする(Task, Observable, async/awaitの活用) • DIをメインに使った開発 • static変数を使った参照解決をしない • GameObject.Find禁止
Slide 24
Slide 24 text
ワークフローの話
Slide 25
Slide 25 text
といっても大したことはしていない • 個人開発なので大したワークフローは無い • どういう順番で作ったかの話
Slide 26
Slide 26 text
製作期間 • 4日(約30時間) • 土日全部と、平日の夜中
Slide 27
Slide 27 text
制作の流れ 1. 通信デバッグ用のビルドを作成 2. VR/AR対応前の状態で動作確認 3. ARCoreを使った実装(InstantPreview) 4. Android実機確認 5. VR実装 6. 結合して動作確認
Slide 28
Slide 28 text
実機確認はツライ • 機材トラブルで時間を取られる • ビルドが遅い • 物理的に機材を使う手間がしんどい • できるだけ実機確認を後回しにする • もちろん、技術検証だけは先にやっておく
Slide 29
Slide 29 text
VRとARを同時にデバッグするのは無理 • VR側の動作確認には、Viveを装着する必要がある • AR側の動作確認には、スマホを持って移動する必要がある • 1人じゃ無理!!!!!!
Slide 30
Slide 30 text
デバッグ用のビルドファイル • アバターがアニメーションを自動再生するだけのビルド • VR側のモック化として利用 • 通信機能だけ実装しておき、モーションデータを送信する @UTJ/UCL
Slide 31
Slide 31 text
シンプルなプロジェクトで先に作る • AR、VRは無視して単体で作れるところまで作る • モック化等の小技を駆使してデバッグをする 送信 受信 https://twitter.com/toRisouP/status/995230604928036864
Slide 32
Slide 32 text
ARCoreを導入して実験 • Instant Preview機能が便利 • USB接続されたスマホを使ってUnityEditor上でデバッグできる ←先程のデバッグ用ビルド https://twitter.com/toRisouP/status/995640657195581440
Slide 33
Slide 33 text
VR側を実装 • SteamVRを導入して実装 • 詳しくは後述
Slide 34
Slide 34 text
あとは最終確認 • VR側役をやってくれる友人を用意 • 時間を合わせて起動して動作確認する https://twitter.com/toRisouP/status/996763932328058881
Slide 35
Slide 35 text
「ワークフロー」のまとめ • コア部分は先に作っておくと楽 • AR実装、VR実装、それぞれで共通して動かせる部分を先に作る • AR/VRの状態をモック化できるようになってるとなお良い • ARとVRはプロジェクトを分けるべきだった • Switch Platformがツライ
Slide 36
Slide 36 text
VRMの使い方
Slide 37
Slide 37 text
VRMとは • VRアプリケーション向け人型3Dアバターフォーマット • https://dwango.github.io/vrm/
Slide 38
Slide 38 text
VRMファイルを探すには • ニコニ立体で探すのが良い • 利用許可なライセンスのモデルを探して利用 • 今回はニコニ立体ちゃんを使用 https://3d.nicovideo.jp/works/td32797
Slide 39
Slide 39 text
Unityで使うためには • UniVRMを導入する必要がある • githubから導入すればOK • https://github.com/dwango/UniVRM • バージョンアップが頻繁 • (まだ安定している感じはしない)
Slide 40
Slide 40 text
Unity上でのVRMの取り扱い方 • 2パターンある • Prefab化する方法 • 動的にロードする方法
Slide 41
Slide 41 text
Prefab化する方法 • vrm拡張子のファイルは自動的にロードされてPrefab化される • ビルドファイルにモデルを埋め込むならこの手法が楽 • あとからユーザがモデルを差し替えるみたいなことはできない手法
Slide 42
Slide 42 text
動的ロードする方法 • ランタイムロードしてモデルを生成する • 後から自由にモデルを変更できるようにするならこっち • VRMの使い方として、おそらくこの方法がメイン • 今回はこちらの方法でやる 直接ファイルパスを指定してロードする場合
Slide 43
Slide 43 text
おすすめのロード方法 • 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
Slide 44
Slide 44 text
動的ロードしたVRMはどうなるのか • コンポーネントがアタッチされたGameObjectが生成される
Slide 45
Slide 45 text
最初からアタッチされてるコンポーネント ←メタ情報が格納されたコンポーネント ←身体の構造の設定値が格納されたコンポーネント ←表情を制御するコンポーネント ←HMDを配置するときに使うコンポーネント ←視線制御に使うコンポーネント ←同上
Slide 46
Slide 46 text
オリジナルの制御を加える場合は • AddComponentで自作コンポーネントを設定する • 同時に初期パラメータもこのタイミングで設定する • 初期化完了のタイミングを通知する機構を用意すると便利 指の曲げ制御コンポーネント https://github.com/TORISOUP/AR_VR_Viewer/blob/master/Assets/VrmArPlayer/ Scripts/Scene/Main/Common/AvaterController.cs#L46
Slide 47
Slide 47 text
動的ロードは結構めんどうくさい • 初期化を非同期にしていかないといけない • VRMの読み込みにまず数秒かかる • スクリプトからコンポーネントの初期化が必要になる • AddComponentしたコンポーネントを手動で初期化する必要がある • 他のコンポーネントに依存する場合はその参照解決が必要
Slide 48
Slide 48 text
VRMアバターの制御
Slide 49
Slide 49 text
今回組み込んだ機能は3つ • 表情の操作 • 指の曲げ伸ばし操作 • リップシンク
Slide 50
Slide 50 text
表情 • Viveコントローラのタッチパッドで表情を変更する 喜 怒 楽 哀
Slide 51
Slide 51 text
表情の変え方 • VRMBlendShapeProxyコンポーネントを使えばOK ←これ
Slide 52
Slide 52 text
コントローラ操作で表情変更 • VRMBlendShapeProxy.SetValue()を使って設定する • 0 – 1の範囲で指定 タッチパッドを触った座標(2次元ベクトル)と設定された表情のベクトルとの内積をとった値を使う https://github.com/TORISOUP/AR_VR_Viewer/blob/master/Assets/VrmArPlayer/ Scripts/Scene/Main/Common/AvaterController.cs#L137-L140
Slide 53
Slide 53 text
表情変更:ポイント1 • 表情を合成する場合はSetValue()の第三引数にfalseを指定 • trueの場合はその時の値で強制上書きになる • falseを指定した場合はApply()を呼び出すと合成値が反映される このタイミング(Update()内)ではすべてfalseにしておく LateUpdate()のタイミングでApply()
Slide 54
Slide 54 text
表情変更:ポイント2 • Lerp(線形補間)を入れると柔らかくなる Lerpなし Lerpあり https://twitter.com/toRisouP/status/995322292346306560
Slide 55
Slide 55 text
指の曲げ伸ばし • VRMにデフォルトでは用意されていない • スクリプトを自分で用意する必要がある • FingerControllerコンポーネント (みゅみゅさん作のスクリプトを許可をもらって改変・配布) • これを動的にアタッチして使う https://github.com/TORISOUP/AR_VR_Viewer/blob/master/Assets/VrmArPlayer/ Scripts/Scene/Main/Common/FingerController.cs
Slide 56
Slide 56 text
コントローラ操作で指の曲げ伸ばし • 各コントローラのトリガーキーの入力を反映 • 曲げる/伸ばす の2段階のみ https://github.com/TORISOUP/AR_VR_Viewer/blob/master/Assets/VrmArPlayer/ Scripts/Scene/Main/Common/AvaterController.cs#L44
Slide 57
Slide 57 text
手の曲げ伸ばし:ポイント • 2段階しかなくてもLerpを入れればなめらかになる https://twitter.com/toRisouP/status/995312888070860801
Slide 58
Slide 58 text
リップシンク • 音声に合わせて口パクする機能 • 今回は Oculus Lipsync Unity を使った • https://developer.oculus.com/downloads/package/oculus-lipsync- unity/
Slide 59
Slide 59 text
リップシンク設定 • 音声の解析結果をそのままBlendShapeに反映すればOK • OVRLipSyncContextコンポーネントが解析結果を保持している https://github.com/TORISOUP/AR_VR_Viewer/blob/master/Assets/VrmArPlayer/ Scripts/Scene/Main/Common/AvaterController.cs#L81-L93
Slide 60
Slide 60 text
VRM まとめ • アバター制御の基本的な機能が揃っており便利 • Humanoidの制御に必要なことは最低限はできそう • 「動的ロード」はちょっと難しめ • プログラムが書けないとキビシイ • まだ出て間もないのでドキュメント不足気味
Slide 61
Slide 61 text
ネットワーク同期の話
Slide 62
Slide 62 text
ネットワーク同期する情報 • アバターの姿勢 • 頭、腰、手先、足先の座標と角度 • コントローラ入力値(表情・手の曲げ伸ばしに使用) • タッチパッドの座標とトリガーキーの状態 • ARカメラの座標 • VR空間内にARカメラがどこにあるかを表示するため
Slide 63
Slide 63 text
ネットワーク同期のやり方 • PUN (Photon Unity Networking) の機能をそのまま使うだけ https://github.com/TORISOUP/AR_VR_Viewer/blob/master/Assets/VrmArPlayer/ Scripts/Scene/Main/Common/AvaterSynchronizer.cs#L90-L134
Slide 64
Slide 64 text
ハマりどころ • VRMの動的ロードとPhoton Cloudの相性が悪い • Photon Cloudの同期の仕組みに乗せるにはPrefab化が必要 • VRMの動的ロードを使っているとPrefabが用意できない • VRMのアバターを直接同期する仕組みにすることができない
Slide 65
Slide 65 text
図解 VRMの動的ロードを使うと同期ができない (PhotonViewはAddComponentできないため) アバター アバター 通信
Slide 66
Slide 66 text
解決策 • 「同期管理オブジェクト」と「アバター」を分離して作る • アバターを独立したGameObjectとして生成する • アバターが生成されたら同期管理オブジェクトに登録する • 同期管理オブジェクトがアバターの情報を同期する
Slide 67
Slide 67 text
図解 同期オブジェクトを仲介させることで、 データの同期を実現する アバター アバター 通信 同期オブジェクト 同期オブジェクト 姿勢書き込み 姿勢反映
Slide 68
Slide 68 text
アバター生成時に同期登録 アバター生成完了イベントが来たら 同期管理オブジェクトへ登録する https://github.com/TORISOUP/AR_VR_Viewer/blob/master/Assets/VrmArPlayer/ Scripts/Scene/Main/Common/AvaterScynchronizeDispatcher.cs#L51
Slide 69
Slide 69 text
同期オブジェクトの様子 • 白い箱が可視化した同期用オブジェクト
Slide 70
Slide 70 text
コツ • 受信側で姿勢の再現時にもLerpを入れるといい感じ • 補間が入って動きがなめらかになる https://twitter.com/toRisouP/status/995579063405195264
Slide 71
Slide 71 text
設定ミスするとこんな感じになる • 同期の設定ミスったときのやつ https://twitter.com/toRisouP/status/995565615405387776
Slide 72
Slide 72 text
ネットワーク同期 まとめ • Photon Cloudを使えばクライアント実装のみで完結する • VRMの動的ロードと合わせるには工夫が必要 • 同時接続数は1部屋あたり10人くらいが限界そう • Photon Cloudの制約(メッセージ数上限) • デモ用途なら十分 • 不特定多数への生放送に用いるには専用のインフラ構築が必要
Slide 73
Slide 73 text
VR側の実装の話
Slide 74
Slide 74 text
Steam VRを導入 • Asset Storeから導入する
Slide 75
Slide 75 text
IK • 終端を指定し、そこに向かって関節を制御する機能 • Inverse Kinematics(逆運動学)
Slide 76
Slide 76 text
IKの対象にVRコントローラを指定 • HMDやコントローラの座標をIKに使うことで、アバターが 操作できるようになる • 今回はFinal IKに同梱されているVRIKコンポーネントを利用した
Slide 77
Slide 77 text
Final IK • Unity向けのIKアセット • VR対応
Slide 78
Slide 78 text
実装 VRのときはコントローラのTransformをIKのターゲットにする ARのときは同期オブジェクトをIKのターゲットにする https://github.com/TORISOUP/AR_VR_Viewer/blob/master/Assets/VrmArPlayer/ Scripts/Scene/Main/Common/AvaterScynchronizeDispatcher.cs#L81-L94
Slide 79
Slide 79 text
VR実装 まとめ • vtuberを実装する方法をそのまま行うだけ • ググったら情報いっぱい出てくる • VRで「結月ゆかり」になって生放送する https://qiita.com/toRisouP/items/14fe62f89808013f9f6e
Slide 80
Slide 80 text
AR実装の話
Slide 81
Slide 81 text
ARCore SDKを導入 • Githubからダウンロード • https://github.com/google-ar/arcore-unity-sdk/releases/tag/v1.2.0
Slide 82
Slide 82 text
Instant Preview • USBで繋いだスマホを使って直接デバッグできる • Unity Editorで実行ボタンを押すだけ
Slide 83
Slide 83 text
サンプルコードをそのまま流用 • HelloAR • 平面を認識してタップした位置にドロイド君を表示するサンプル • これを流用し、タップ地点の座標を取り出せるようにした
Slide 84
Slide 84 text
実装 • ArViewManager https://github.com/TORISOUP/AR_VR_Viewer/blob/master/Assets/VrmArPlayer/ Scripts/Scene/Main/ForSmartphone/AR/ArViewManager.cs#L107-L114
Slide 85
Slide 85 text
タップ位置を基準座標にする • アバターの親Transformの座標をタップ位置に設定 https://github.com/TORISOUP/AR_VR_Viewer/blob/master/Assets/VrmArPlayer/ Scripts/Scene/Main/ForSmartphone/StageController.cs#L56
Slide 86
Slide 86 text
タップした位置にアバターを表示
Slide 87
Slide 87 text
アバターの表示サイズの変更 • uGUIのスライダーをいじるとアバターのサイズが変わる • TransformのScaleを直接変更している • 小さくしすぎると足のIKがおかしくなる
Slide 88
Slide 88 text
IKが壊れる理由 • IKの設定値の調整不足 • アバターのサイズが変わったらIKの設定も同時に変更する必要がある (歩幅、股の開き具合など) • 単にこの調整機能を入れ忘れていただけ…
Slide 89
Slide 89 text
Androidビルドして実機確認 • 動かすとだいたい最初は上手くいかない
Slide 90
Slide 90 text
動かなかった理由 • パーミッションが足りない • マイクが不許可になってた • カメラの認可ダイアログは出たのに、マイクは出なかった • モデルデータがロードできない • StreamingAssetsはWWWでしかロードできない問題と衝突 • UniVRMをそのまま使うとFile.ReadAllBytesでVRMをロードしようとする
Slide 91
Slide 91 text
Androidビルドでデバッグするときは • Android Device Monitorが使える • Android SDKについてくるログ閲覧ツール • ビルド時にDevelopment BuildにするとDebug.Logがここに流れる
Slide 92
Slide 92 text
問題発生:Windowsビルドが通らない! • ARCoreを導入するとWindowsビルドが通らない • スタンドアローンビルド向けのdllが用意されていないから
Slide 93
Slide 93 text
回避策 • Android向けdllを無理矢理よみこませてビルドする • かなりバッドノウハウ • やはりARとVRでプロジェクトを分けたほうが良さそう… これを追加して無理矢理よみこませる
Slide 94
Slide 94 text
AR実装 まとめ • ARCoreのサンプルコードをそのまま使っただけ • ARCoreの自体の機能はほとんど活かせてない • VRプロジェクトとの混在は避けたほうが良さそう • ビルドは無理矢理通るようになったけど、 今度はInstant Previewがおかしくなった
Slide 95
Slide 95 text
その他実装のコツ
Slide 96
Slide 96 text
その1:処理の非同期化 • アバター読み込み、ネットワーク通信などで非同期処理が多い • async/await & UniRx が大活躍
Slide 97
Slide 97 text
UniRx • Reactive Exntensions for Unity • 非同期処理、イベント処理に強くなるライブラリ • Asset Storeから導入可能(無料) • MITライセンス
Slide 98
Slide 98 text
愚直に書くと… • Actionコールバックだらけ • コルーチンもなんとかしたい
Slide 99
Slide 99 text
async/await + UniRx • コルーチンを使わずにWWWをawaitで待てる • VRMのロードもawaitで待てる
Slide 100
Slide 100 text
Photonの初期化周りの処理 • PhotonRxを導入するとPUNのメソッドをTask化できる • https://github.com/TORISOUP/PhotonRx
Slide 101
Slide 101 text
PhotonRx + Task + UniRx • ボタンが押されたらログイン→処理が終わるまでボタン無効化 https://github.com/TORISOUP/AR_VR_Viewer/blob/master/Assets/VrmArPlayer/ Scripts/Scene/Title/LoginPresenter.cs
Slide 102
Slide 102 text
AsyncReactiveCommand • 説明ややこしいのでQiitaみて • 【UniRx】ReactiveCommand/AsyncReactiveCommandについて • https://qiita.com/toRisouP/items/c6fba9f01e6d15dabd79
Slide 103
Slide 103 text
その2:設計の話 • どのモードで動いているか意識せずに作りたい • いまARなのか、VRなのかをできるだけ意識せずにコードを書きたい • オープン・クローズド原則を守りたい
Slide 104
Slide 104 text
どういうこと? • たとえば「コントローラ入力」 • VR時:Viveコントローラの入力を使う • AR時:ネットワーク通信で送られてきた値を使う • デバッグ時:キーボードの入力を使いたい • これをif文で書き分けるみたいなことはしたくない • DIで乗り切ろう
Slide 105
Slide 105 text
DI(依存性注入) • 抽象化した場所に、具象クラスを後から指定する • クラスを差し替えるだけで挙動を後から変更できるようになる
Slide 106
Slide 106 text
Zenject • Unity向けのDIのフレームワーク • DIするならこれが便利 • Asset Storeから導入可能(無料) • MITライセンス
Slide 107
Slide 107 text
抽象化 • 入力イベントを発行するインタフェースを定義 • UniRxのReactiveProperty化が便利 https://github.com/TORISOUP/AR_VR_Viewer/blob/master/Assets/VrmArPlayer/ Scripts/Scene/Main/Common/Inputs/IInputEventProvider.cs
Slide 108
Slide 108 text
利用時はこのインタフェースのみを触る • 実体がどのクラスであるかは無視して書く • 使うときはインタフェースしか意識しない
Slide 109
Slide 109 text
Installer(Zenject) • どのインタフェースにどの実装を使うかを定義する機能 • このインタフェースにはこのクラスを使う、みたいなのを書く場所 読み方 IInputEventProviderおよびIInputSetableが要求された場合は、 VrInputEventProviderを注入する(その際は同じインスタンスを使い回す)
Slide 110
Slide 110 text
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
Slide 111
Slide 111 text
SceneにそのInstallerを配置する • シーンを切り替えると自動的にDIする実装が切り替わる VR用のシーンで使うInstaller
Slide 112
Slide 112 text
後はそのまま実行すれば終わり • 設定に応じて自動的に実装が注入される • SceneLoad時に自動的に注入されていく
Slide 113
Slide 113 text
DIはムズカシイ • 疎結合な設計ができてないと効果がない • オープン・クローズド原則 • 依存関係逆転の原則
Slide 114
Slide 114 text
設計の勉強をするには • この資料を見て • Unity開発で使える設計の話+Zenjectの紹介 • https://www.slideshare.net/torisoup/unityzenject
Slide 115
Slide 115 text
Zenjectを使う上での注意点 • DIの実行にはオブジェクトの存在をZenjectに認識させる必要 がある • 直接Instantiateしたり、AddComponentするとDIされない • あらかじめSceneに配置しておくか、Zenjectのコンテナ経由で GameObjectを作る/AddComponentを実行する必要がある
Slide 116
Slide 116 text
Photonと相性が悪い • Photon.Instantiateで生成したオブジェクトはZenjectが 検知できない • Photon経由で作ったオブジェクトはDIが実行されない
Slide 117
Slide 117 text
解決策 • ZenAutoInjecterコンポーネントをアタッチする • これを対象につけておくとオブジェクト生成後にZenjectに認識される • 後追いでDIが実行されるようになる
Slide 118
Slide 118 text
ZenAutoInjectorを使う上での注意 • DIのタイミングがいつになるかわからない • Start()の実行までにDIが実行されないことがある • DIが終わったことを検知して処理を開始する仕組みにしよう
Slide 119
Slide 119 text
DIの実行を検知する方法 • メソッドインジェクションを使う • DIが実行されたタイミングでメソッドが実行される • その中でフラグを立てるなり、イベント飛ばすなりすればよい https://github.com/TORISOUP/AR_VR_Viewer/blob/master/Assets/VrmArPlayer/ Scripts/Scene/Main/Common/SynchronizeCamera.cs#L30-L42
Slide 120
Slide 120 text
その他実装のコツ まとめ • 非同期処理は対処法を知っておくべし • async/await, Task, UniRxの使い方を覚えておくと良さげ • Zenjectを使ったDIが非常に便利 • 無駄なif文/switch文を減らせる • わざわざマネージャクラスをシングルトン化する必要がなくなる • デバッグやテストがやりやすくなる
Slide 121
Slide 121 text
さいごに
Slide 122
Slide 122 text
今回作ってみた感想 • VRとARとネットワーク同期といろいろ盛りすぎた • やってることに対して作るのがめっちゃしんどい • でも未来は感じる • プログラマ的には楽しかった • 非同期処理の多用&DIの多用 • キレイにDIがハマると嬉しい
Slide 123
Slide 123 text
現状の問題点 • 技術デモの領域を出ない設計になってる • VR1人-AR1人、の1対1通信を想定した作りになってる • VR複数-AR複数、の多対多は現状の設計じゃ無理 • スケール性がない • まともにサービス化するなら通信サーバの開発、インフラ構築が必要 • 個人開発じゃ技術デモくらいが限界
Slide 124
Slide 124 text
さいごにまとめ • VR空間をARで可視化するのは夢がある • AR/MRデバイスがもうちょっと普及してくれたらありがたい • VRMが便利でオススメ • 簡単に人型アバターを動的ロードして扱えて良さげ • 今後の3Dコンテンツの主流フォーマットになってほしいな
Slide 125
Slide 125 text
おわり