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

おわり