[誰得]全デバイス対応STYLYシーンを制作せざるを得なくなった時に気をつけること

こちらは[STYLY Advent Calendar 2023](https://qiita.com/advent-calendar/2023/styly) 9日目の記事です。

# はじめに
皆さんは[STYLY](https://gallery.styly.cc/)という国産XRプラットフォームがあるのはご存知でしょうか。このプラットフォームはVR、AR両方作れる上、最近はPico4によるビデオシースルーにも対応しました。デバイスとしてはWeb、Mobile(Android/iOS)、VR HMD(スタンドアロン/PC)ととても幅広いデバイスに対応しています。STYLY Sessionを利用すれば複数人でのシーン体験も提供できます。

そしてこんな記事を開いて見ているあなたはきっと今まさにプロジェクトを起こし、なんでもありのSTYLYを活用して制作する気になっているということでしょう。
そんなあなたへ私が一つ忠告するなら、

**全デバイス対応という考えは今すぐやめてください**

ここで言う全デバイス対応とは、VR作品でWeb、Mobile、VR HMDの全てに対応する場合です。さらに言えばSTYLY Sessionにより複数人でも見れるようにする場合です。
AR作品を作ろうとしている方は関係ありません、Mobileだけなので安心です。とはいえ最近はARコンテンツをVR HMDビデオシースルーで表示できるようになっているので、完全に無関係とは言えません。

それでも制作せざるを得ないときがあります。私も過去にはそんな制作をしました。[あれ](https://rojohaku.com/vraburatsubo/)とか、[これ](https://www.kahaku.go.jp/3dmuseum/EMI-VR/)とか。そんな私の過去の知見をもとに**気をつけるべきこと**を思いつく限りお伝えする記事となります。

# 全デバイス対応で気をつけるべきこと
まず総論としてそれぞれのデバイスによってターゲットユーザーが違うことを認識すべきです。それぞれのデバイスによって、ユーザーのペルソナを以下のように想定できます。
* **Web**：アプリインストールせず気楽に体験したい、あまりスマホリテラシーが高くない人
* **Mobile**：すでにSTYLYをインストールしている人、スマホしか持っていない人
* **VR HMD** : VRを趣味に持ち、VRリテラシーが高い人

以上のことから、**全デバイス対応する＝普段からVRに触れていないエントリーユーザーからVRリテラシーの高いユーザーまで広いターゲット設定をしたプロジェクト**であるということが言えます。プロジェクトがこんな選択をする場合、ターゲットユーザーの分析できてるか怪しいところです。正しくボリュームゾーンを選定し、ターゲットユーザーを設定し直すべきです。だから私はやめるべきだと初めに忠告さしあげたわけです。ですが世の中にはこの広大なターゲットユーザーを設定するプロジェクトが結構あるのが実情です。というわけで作る時の**考え方**、**各デバイスによって違うこと**、**作るときのお役立ち情報**をまとめます。

（余談ですが上記のターゲットユーザー向けに展開した過去のプロジェクトのデバイス毎ユーザー分布はWeb:Mobile:VR=5:4:1位でした。）

## ターゲットデバイスの考え方
全デバイス対応のコンテンツを公開する際、ランディングページなどで対応デバイスを記載します。例えば以下の様な具合ですね。
```
PCブラウザ
● OS：Windows10以上、macOS 10.15以上がインストールされたPC
● メモリ：4GB以上（8GB推奨）
● ブラウザ：Google Chrome推奨

スマートフォン/タブレット
● 対応機種はARが利⽤できるタブレットやスマートフォンです。
● iPad/iPhone対応機種一覧
  下記リンク先ページ下部に記載の「対応デバイス」をご確認ください。
  外部サイトhttps://www.apple.com/jp/augmented-reality/
● Android対応機種一覧
  外部サイトhttps://developers.google.com/ar/discover/supported-devices#google_play_devices

VRゴーグル
● VRゴーグルによっては健康と安全に配慮して、お⼦様の年齢制限が設定されていることがあります。各デバイスの説明書の注意事項をよく読んで安全にご利⽤ください。
● 動作確認済みの視聴環境
  Steam VR対応ゴーグル：MetaQest2/3(Quest Link接続)
  スタンドアロンゴーグル：MetaQest2/3
```
上記の内容は2023/11時点での内容なので、現在のSTYLYの対応デバイスに合わせてアップデートして記載いただくと良いです。

重要なことは、ここに記載した内容がそのままコンテンツの動作保証をする範囲、テストスコープになります。また、ユーザーサポートとして各デバイスごとの操作方法と体験開始方法を記載する必要性もありコストが高くなります。何度も言いますがターゲットデバイスを絞れるなら絞るべきです。例えば、最近はQuest2/3が売れてユーザーが多いのでSteamVR対応はしなくてもいい、という選択ができそうです。

ともあれ、まずはターゲットデバイスの対象とスペックを定義することを、プロジェクトの一番初めに行いましょう。

## コンテンツのファイルサイズの考え方
ユーザーがコンテンツを開くとき、何秒待てるでしょうか？

先程の例でいうと、ランディングページからSTYLYコンテンツを開き、ロード後にVR空間が表示されます。この表示されるまでの時間です。場合によってはWiFiへの接続やSTYLYアプリのインストールも含めて考えるべきでしょう。WiFiやSTYLYアプリのインストールに関しては手順として減らしようがないので、その手順をわかりやすく伝える以上の改善はできないでしょう。ここで時間を大きく減らせるのは、コンテンツのロード時間になります。コンテンツのロードには２つの工程があります。
1. コンテンツファイルのダウンロード時間
1. ファイルのロード時間

ファイルのロード時間はコンテンツの作り込みの量に概ね比例します。そして同時にコンテンツのファイルサイズに影響が出ます。イマーシブでエレガントなコンテンツは大量の表現が実装されており、その分アセットが大量に使われファイルサイズが大きくなりがちです。ですがファイルサイズを大きくするとダウンロード時間に影響が出て、コンテンツ開始まで時間がかかり、結果ユーザー離脱のリスクが上がります。

ですから、プロジェクト開始時にコンテンツのファイルサイズ目標を設定することがとても重要です。
ここでターゲットとするネットワーク環境は一番チープなMobileのキャリア回線利用時です。Mobileの場合WiFi利用することを明記してもキャリア回線を利用する人は絶対います。なのでキャリア回線利用時を前提に目標設定をしましょう。WebとVR HMDは根本は光回線なので安定しているので一旦無視します。

キャリア回線の[4G平均実効速度は290Mbps](https://www.docomo.ne.jp/area/effective_speed/)という値が公開されていました。25%値で170Mbps、ワーストで4Mbps。
一方でユーザーが待てる時間はまず6秒、おおくて30秒というのが体感でしょうか。YoutubeやSNSなどで動画をザッピングするとき何秒見て切り替えるか考えると、それが答えな気がします。
そうすると**ファイルサイズは大体70MB(=170Mbpsで約4秒)、多くて100MB**というのが関の山でしょう。

このファイルサイズ指標に関して２つ例外があります。
1つ目がコンテンツの切り替えを行う場合です。STYLYには[シーンを切り替える機能](https://styly.cc/ja/manual/customaction-kotauchisunsun-change-styly-scene/)があり、複数のシーンを行き来することができます。この切り替え先のシーンについては、若干ファイルサイズが大きくてダウンロード時間が長くても、ユーザーは次の空間に対する期待があるので待ってくれることでしょう。
2つ目にコンテンツロード後に動的に[画像](https://hutonggames.fogbugz.com/default.asp?W698)や[動画](https://styly.cc/ja/manual/customaction-tomo-video-init/)を表示することです。動的に読み込むリソース類はコンテンツが表示されるまでの時間に影響を与えません。
これらを前提に空間設計、各ファイルの取り扱いを事前に検討すると良いでしょう。

制作したコンテンツのファイルサイズは、STYLY Mobileでコンテンツを一度開くと表示されます。こちらで適宜確認しつつ作るのが良いでしょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197699/c00825cf-3778-92d4-9b33-7790477c25fb.png)

## クオリティコントロールの考え方
コンテンツのクオリティについて最大の問題は、それぞれのデバイスの特徴を使いこなせないので、尖ってない中庸なコンテンツになりがちな点です。

VR HMDに特化すると、没入感があり、全身を使った体験を構築できます。PC VRならスペックに余裕があるので圧倒的な画作りができますね。モバイルなら本体のジャイロやいつものスワイプ操作、バイブレーションなどの機能も使えることでしょう。
ですが、いまやろうとしていることは全デバイス対応です。前述のどおりファイルサイズの制限があり、何よりもMobileやWebブラウザ環境で利用できるCPU,RAMは少なく、余裕は到底ありません。このチープな環境に合わせて作り込むしかなく、クオリティもそこそこで中庸な仕上がりになることでしょう。なんだったらライティングなどしっかり絵作りしてもSTYLYのWebとPC VRではUnityのQuality設定が大きく違う為、完成後に各デバイスで動作確認したら全く違う色味でレンダリングされるということはザラにあります。
ロジックに関しては各デバイスごとに動作を作り分けることは可能ですが、デバイスごとのユーザー体験は全く別物になりテスト工数が大きく膨れ上がることでしょう。

つまり初めのうちに、共通のトンマナ、UIUXをデザインし、その通りに表現できるか全デバイスでフィジビリティを取るべきです。このベースラインができて初めて、デバイス固有の実装を検討できます。

## コンテンツの公開期間の考え方
あなたのプロジェクトのイベント会期は何時から何時までですか？

STYLYは生物です。気軽に成長します。時に破壊的アップデートをすることがあります。とても長い会期を設定する場合、STYLYのアップデートに合わせてコンテンツを保守する必要性があります。逆に会期が短いなら、あまり気にする必要性はありません。長い時間公開する場合とは、私の体感上3か月以上公開するパターンです。この時、STYLYでアップデートされる要素は以下がありえます。
1. Unity
1. PlayMaker
1. STYLY Pluginに含まれるInteractionSDK、PlayMaker CustomAction

これらは日々アップデートの危険に晒されていることをまず認識しましょう。最近のSTYLYには優秀なQAが居るので、後方互換性を保てています。(いつもありがとう！！)
ですが、後方互換性を保てないときは保てません。それを見越して、あまり影響がない実装を心がけるべきです。例えば、PlayMakerを使わずにInteractionSDKだけでインタラクションを実現する、などです。

また、近々デバイスがディスコンになりそう/なったものは使用を控えるべきでしょう。大きなところではGoogle MirageSoloやMeta Quest初代あたりでしょうか。MobileもARCore/ARKit対応機種の変動や、Androidでいえば[APIレベル要件](https://support.google.com/googleplay/android-developer/answer/11926878?hl=ja)の更新による対応機種の変動があります。これらはSTYLYの努力に関わらず発生することであり不可避です。

長期間対応するということは、適宜時代の変動に対応する運用保守コストを支払うという選択に他なりません。あなたのプロジェクトでは運用保守費を予算計上し継続的に捻出できますか？できないのであればイベントを数週間に絞る選択もやむなしです。

## 制作コストの考え方
さて、ここまでの考えを理解すると制作コストが見えてきます。
1. 対応デバイスをどこまで広げるか
1. デバイス固有実装は行うか
1. イベント期間はどれほどか
1. トンマナとUIUXの実装にどれほど拘るか

ここで純然たる事実を言うと、全デバイスに対応するとしても、全て共通実装で表現できる範囲に内容を抑える場合、逆に制作コストは低い可能性があります。つまり、共通のSTYLYシーンを1つ作り各デバイスでテストを行うのが最小であり最速です。ですがデバイス固有の実装が増え、場合によってはデバイスごとにSTYLYのシーンを分けることになると、実装コストとテスト工数が跳ね上がります。あなたのプロジェクトはどこまで許容できますか？

ここまではプロジェクト初期に考えることをまとめてきました。
ここからは制作が始まってから気をつけるべきことをまとめていきます。

## STYLYでVRコンテンツを作る
STYLYにおけるVRの定義は何でしょうか。STYLYStudioでVRTemplateでシーン制作を開始すること？Publishする時に#VRタグを付けること？いいえ、違います。

答えは**Skyboxがシーン開始時1Frame目に存在するかどうか**です。

Skyboxが設定されていればVR、設定されてなければARです。
Unityの設定からWindow->Rendering->Lighting SettingからSkybox Materialを何でもいいので設定しましょう。ARならNoneにしてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197699/ebb4424b-9c68-ef23-8c89-917baba0e748.png)

1Frame目が過ぎてしまえばなんでもOKです。PlayMakerで`Set Skybox`を利用して変更するも自由です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197699/1760e790-8925-2b8a-7489-303c72623db0.png)

## タイトル、詳細、タグ、サムネ、ユーザー名の表示のされ方が違う
STYLYではPublishする時に様々な項目を設定できます。また、アカウント情報も設定できます。これらの項目について、公開したコンテンツがユーザーからどう見えるのか知っておくことが重要です。そして、プロジェクトで利用するユーザー動線でどう見えるのかを知ることが重要です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197699/bf357023-102d-898a-bce7-00a41b94e39f.png)

Webの場合、埋め込み機能があります。以下のスクリーンショットの通りアカウントロゴとコンテンツタイトルしか表示されません。
参考 [国立科学博物館 The Wildlife Museum](https://www.kahaku.go.jp/3dmuseum/yoshimoto-vr/)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197699/141649b5-7074-afa9-ce25-ffa023c71253.png)

MobileのGallry画面では一通り表示されますが、一方でMobileへの直接Linkから起動するとユーザー名とタイトルが表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197699/02141707-30e6-ee28-34a3-0dd4f81739ca.png)

他にも様々な選択肢がありますが、ここでのポイントは説明欄に書いても見られることはほぼないということです。ユーザーの目につくものは体裁を整え、それ以外はランディングページなど掲載できる場所に掲載しましょう。

## 静止画撮影/動画撮影が違う
Mobileの場合静止画撮影/動画撮影するための機能があり、それらのUIがデフォルトでONになっています。一方でWebやVR HMDはOS機能を利用して撮影する流れのみ提供されています。これは、STYLY MobileがSNSでの画像共有を目的として作られている為です。
プロジェクトの方針で撮影NGとする場合、コンテンツ側でMobileの撮影機能やOS機能を制御することはできない為、コンテンツ表示前に撮影NGの旨の同意を求めるなどするほかないでしょう。
逆にSNSでの露出を増やすために撮影を推奨したい場合、Mobileのみがターゲットデバイスになるという前提を持つべきです。全デバイスで推し進める場合、事前に各デバイスでの撮影方法をランディングページなどに掲載すべきでしょう。

## デバイスごとにアスペクト比と画角(FOV)が違う
各デバイスでアスペクト比は様々です。また、画角(Field of View)はSTYLYのMainCameraの設定により一部デバイスで変更されています。

* Web : 大体16:9、**FOVは80で魚眼表示になる** 
* Mobile : **スマホ次第でアス比もバラバラで縦横きりかえがアリ**、FOVは60
* VR HMD ： 人の目に依存するので約16:9、FOVは60

これによって重大な問題が2つ発生します。それは、ロード完了直後のビジュアルを作りこめないこと。そして、最適なコンテンツ配置が共通化できないことです。

**問題①ロード完了直後のビジュアルを作りこめない**
ロードが完了し空間が表示された直後は、チュートリアルやユーザー動線など表示するものが多いです。これらを程よく視界に入る程度にするためにSpawn position、STYLYでいうYout positionおじさんを動かしてユーザー初期位置を設定するわけです。が、画角の違いによりデバイス次第では思ったより遠い場所で表示されるということが発生します。

**問題②観察対象が歪む**
Web限定の話ですが、FOVが魚眼寄りなので対象を近くで見ようとすると、画面端に行くほど歪みます。

例としてSpawn地点の目の前にカンジキウサギ3Dモデルを置いてみました。見比べるとウサギの大きさがだいぶ違いますね。また、地面のグリッドが歪んで見えることがわかります。ですが、この2つは同じシーンです。同じWeb環境なのにSTYLY StudioとWebPlayerではここまで大きく違います。ここにさらにMobileのアスペクト比の違いや縦横の切り替えまで考慮して絵作りすることは果たして現実的でしょうか。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197699/053cdf93-72ac-c37d-ac9a-d2bb53c86685.png)

回避策としては、Mobileに関して横画面のみの体験とするといった割り切りができます。ですがWebのFOVに関してはどうしようもありません。また、Mobileの機種ごとにアス比が違うという点もどうしようもありません。諦めて、全デバイスでほどほど見れるくらいにコンテンツを調整しましょう。

余談ですが、PlayMakerを使えばMainCameraのFOV設定をいじれますが、今後とも恒久的にできるとは言えないのでここでは紹介しません。
余談その2として、Mobileの縦横はこの[PlayMaker Device Orientation Event](https://hutonggames.fogbugz.com/default.asp?W490)で取得できます。

## インタラクションが違う
これはSTYLYというより一般的な話です。Webはマウスとキーボード、スマホはタッチ、VR HMDはコントローラー。すべてプレイフィールが違います。結果として、空間内に対するインタラクションの意味が変わってきます。VR HMDのインタラクションを考えると、つかんだり持ったり振り向いたりと主観的な体験が可能です。これに比べるとスマホでのインタラクションは基本的に”つっつく”、”さする”、”スマホを傾ける”体験になります。押しボタンなどこれに準ずるインタラクションは体験を伴いますが、それを除けばガラスの向こうの出来事でしかありません。Webに至っては、すべてのインタラクションが遠い場所で起きていることです。WebやMobileで何かに見立ててインタラクションを実現しても、別のデバイスでは成立しなかったりします。

更に世知辛い現実が、上記のようなインタラクションは各デバイスごとに個別の実装を求められます。例えば、Web向けにPlayMakerの`Mouse Pick Event`を使えばColliderに対するクリックを検知できますが、VR HMDの前には無意味です。Mobile向けにタッチした各指ごとのIDを取得することもできますが、それはMobileだけにしか適応できません。

結局この点においても諦めが必要になります。STYLYでは全デバイス共通のインタラクション実現方法が提供されています。それは[Interaction SDK](https://styly.cc/ja/manual/interaction_sdk_manual/)とButton Componentです。Interaction SDKは掴んだりタイマーを設定したりといったVRあるあるの一通りのインタラクションを提供してくれます。詳細は[公式マニュアル](https://styly.cc/ja/manual/interaction_sdk_manual/)をご覧ください。もう一つの方法として、Button Componentを付けるということです。STYLY上でColliderを付けたオブジェクトを選択する場合、WebやMobileでは突っつくだけですが、VR HMDではコントローラーからRayを飛ばした表現をしたいはずです。STYLYではButton ComponentをつけておけばRayが飛び、選択するとOn Click Eventが発火します。とにかくこれを付けておけばOK！といった感じで気軽にご利用ください。

## 移動の仕方が違う
VR空間内ではユーザーの移動によってストーリーが展開したりと、移動に対する役割が大きいです。ですが先ほどのインタラクション同様に移動も各デバイスごとで差分が大きいです。
大きな要素として、連続的な移動かテレポートか、地面に足がついているかどうか、壁を越えられるか。この3つの要素がデバイスごとに違います。
* Web ：連続的な移動、**地面に足がついていない**、**壁を通り抜ける**
* Mobile : 連続的な移動、地に足がついている、壁を通り抜けない
    * ピンチ操作をすると、**地面に足がついていない**、**壁を通り抜ける**
* VR HMD ： **テレポート移動**、地に足がついている、壁を通り抜けない

特に壁を通り抜ける仕様によって何が起きるのかというと、VR空間内の**見せたくない裏側を見られてしまいます**。全方位どこを見られてもいい空間を作るコストは莫大なものになるので、基本的にすべてを作りこむという選択は当然ありません。次節で話すPlayMakerによるユーザーの強制移動をすればある程度の強制はできますが、STYLYの仕様で何でもできるわけではありませんし、コンテンツ側で判定して強制するのでどうやっても1Frame遅れます。

このことから、VR空間デザインにおいても諦めが必要となります。見られてしまうことを前提に考えるほかありません。それが嫌であればPlayMakerでどうにかするロジックを気合いで組みましょう。
足場の仕様に関しては[公式ドキュメント](https://document.styly.cc/doc/docs/en/creator/creator_teleport_collider/)も参照ください。

## PlayMakerによる強制移動の仕様が違う
ユーザーをPlayMakerを利用して強制移動するということはVRコンテンツを作る際によく思いつく表現です。ですが、デバイスごとに仕様が大きく違うため基本あきらめましょう。
以前私が調査した際の記事[コンテンツによるユーザ移動方法を整理する](https://qiita.com/noria901/items/7e55292124b22e91d5bc)に詳しく書いてありますが、デバイスによってユーザーリグの違いがあるため、向きを変更できなかったり、そもそも移動できなかったりします。

Webに関してはMainCameraをPlayMakerでSetPositionしたら強制移動できるので、先節の壁抜け対策という意味ではこれを気合いで実装したらある程度は対策できます。何にしても、基本的にはユーザーを強制移動するといった思想は持たない方がいいです。やるのであれば空間側を移動するなどしましょう。

## 色の出方が違う
Unity一般論で、カラースペースの話です。STYLYではGammaを利用しています。つまり、これに合わせてテクスチャやShaderを用意する必要性があります。そのうえで、UnityのQuality設定が各デバイスごとに違います。UnityのProject設定はSTYLY側で決め打ちになっているので変更はできません。

上記が基本ですが、以前であった現象として、STYLYのPC VR環境だけカラースペースがLinerっぽい見た目になるということがありました。このときはLinerでもGammaでもあまり発色が変わらないShaderを利用することでどうにかしました。STYLYの仕様ではPC VR環境も含めてGammaのはずなので、根本原因は謎のままです。できることは、初めのうちに使う予定のShaderの色の出方が各デバイスで問題ないか確認することだけです。

## Shaderの制限が違う
Unity一般論になります。基本的にはWebGLの仕様に引っ張られると考えるとよいでしょう。代表的なところでGeometory Shaderがあり、[STYLY公式ドキュメント](https://document.styly.cc/doc/docs/en/creator/creator_plugin_intro/#styly%E3%81%A7%E5%88%A9%E7%94%A8%E3%81%A7%E3%81%8D%E3%81%AA%E3%81%84%E6%A9%9F%E8%83%BD%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6)にもその記載があります。
世の中にあるShader例でいうと、[Kuwamaiさんのポイントクラウドを表示するShader](https://github.com/Kuwamai/PointCloudShader)や、[おにさわさんの切り絵Shader](https://booth.pm/ja/items/4535781)など素敵なものが一杯あります。が、Web環境では動かないです。自身でShader改修するか、代替表現を探すか。頑張って下さい。

## uGUI/メニューの表示の仕方が違う
Unity一般論です。uGUIのRender Mode/ScreenSpaceでUIを画面の前面に表示できますが、VR HMDの場合これは表示されません。Render Mode/World SpaceにするとVR HMDでも表示することができ、STYLYにおいては追加で特に実装しなくてもVRコントローラーでの操作が可能です。
これを前提に実際にUIを実装する場合、Web/Mobile向けとVR HMD向けのUIのデザインを共通にするか別にするかといった選択が発生します。UI内容に合わせて選択いただくとして、どちらにしてもVR HMDの時だけVR用のUIを表示したいものです。デバイス判定はPlayMakerのSTYLY CustomActionである`Is App Type PCXR`/`Is App Type Standalone XR`で判定可能です。UIを共通実装にする場合、ここでさらにRender Mode/World Spaceに変更する実装をPlayMakerでするとよいでしょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197699/0c001a52-60ab-4e89-32df-41fbd258c06f.png)

## 外部の画像/動画等を取得する際のネットワーク経路が違う
PlayMakerの`WWWObject`により画像やテキストを取得できますが、じつはこの`WWWObject` ActionはSTYLYのProxy経由でのアクセスが発生しています。これの背景についてですが、Webの仕様で[オリジン間リソース共有(CORS)](https://developer.mozilla.org/ja/docs/Web/HTTP/CORS)があります。このCORSの設定次第では別オリジンのリソースを取得できません。例えば[https://aaa.com]()にあるHP上で[https://bbb.com/hoge.jpg]()を表示するにはbbb.comのCORS設定にaaa.comからのアクセス許可が必要なわけです。これはブラウザで表示中のページから直接アクセスを抑制する機能なので、Proxy経由でアクセスすれば影響がありません。つまり、`WWWObject`がProxy経由という仕様は、STYLYが気を利かせてくれているわけです。ですが1点注意が必要で、Proxyの仕様でキャッシュ機能があります。例えば画像を一度`WWWObject`でDLするとProxy上のキャッシュに画像貯めて、2度目のアクセスではキャッシュ上の画像を返す挙動になります。これにより、自前のサーバ上で画像を切り替えても、新しい画像がDLできないという問題が発生するわけです。これの回避方法は、URLの最後に適当なタイムスタンプを加えてしまうという方法です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197699/c1733c1a-925a-b39f-e3b9-177c119cc929.png)

STYLY/Unityには他にも外部アクセスする方法があり、それぞれでProxyがあるかどうか違いがあります。
* Unity Video Player Component : Proxyなし
* PlayMaker WWW Object：Proxyあり
* Cutom Action Get HTTP Request：Proxyなし

サーバ側でCORS許可設定したらいいだけではありますが、もしもうまくDLできないことがあったらこれらの仕様を前提に問題を切り分けてください。

## 動画再生の実装方法が違う
動画再生する場合、UnityのVideoPlayerを使うことが一般的ですが、Web環境では再生できません。また、UnityからSTYLYにアップロードする際、動画はビルド物に含まれません。
まず前者については[PlayMaker CustomAction　VideoInit](https://styly.cc/ja/manual/customaction-tomo-video-init/)を使うことで解決できます。動画は外部サーバに配置し、こちらのCustomActionを用いて再生制御を行います。サーバ配置などに関しても上記のリンク内に記載されているのでご一読ください。

## コンテンツへのユーザー導線が違う
VR体験が始まるまでのユーザー導線は各デバイスによって違います。今あるユーザー導線をざっとまとめると以下があります。
* Web
    * STYLY Galleryでの視聴
    * Web埋め込み(iframe)
    * GalleyへのURLリンク
* Mobile
    * ダイレクトリンク
    * QRコード
* VR HMD(PC)
    * STYLY Galleryからの体験
    * ダイレクトリンク
* VR HMD(Standalone)
    * **STYLYアカウントのマイリスト機能を利用して体験（←つらい）**

例えばランディングページから各デバイスへの体験リンクと体験方法を記載することを考えたとき、スタンドアローンVR HMDは導線を作ることができません。マイリストに登録する流れはSTYLYアカウントを作らないと実現できません。それをユーザーに強いるコストは考えざるを得ません。現状この回避方法はないので、スタンドアロンVR HMDを切る選択するほかありません。

## 各デバイスごとの固有実装を作る
さて、ここまでの違いがある前提でなお各デバイス固有の実装を行い使い分ける場合、PlayMakerによるデバイス判定を行って作り分ける必要性があります。これには以下のCustomActionを利用します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197699/103309f4-cad1-8b1f-7fae-95660a2972b5.png)
PlayMakerのActionウィンドウで出てくる`is App TypeXXXX`がデバイス種別判定になります。また、Mobile環境がVRとARどちらで動いているかは`is Mobile VR`で判定可能です。

## 各メンバーと連携して作る
余談というか、制作に当たってのTipsです。全デバイス対応をするような酔狂なプロジェクトは規模がデカくなりがちです。結果チームメンバーとUnity環境をGithubで共同開発する環境を作ったり。それでもいいですが、STYLYならではの作り方があります。それは、それぞれUnityで制作したものをSTYLY Studio上で取りまとめるという方法です。例えばライトベイクしたSceneとPlayMakerロジックをまとめたPrefabを別で制作してSTYLY Studio上で配置するといったやり方です。これはつまり、Prefabで必要十分で性能に影響がない表現や機能ごとに制作担当者を振り分けて作業したら捗るという寸法です。例えばUIなどは影表現が不要なのでベイク対象には含まれないので担当を分けられる、といった寸法です。環境を共有する手間がなかったりビルドする時間を短くしたり。こんな感じでSTYLY Studioには様々な使い道があるのでぜひライフハックしてください。まあ、コード管理の観点で最後どう取りまとめるのかは考えどころですけどね。

# Session対応で気をつけないといけないこと
ここまでは一人で観るシーンの話でしたが、Sessionによる複数人体験を考えるとまだ考慮が足りてません。
というわけでSessionの勘所を説明しておきます。

## 同期するもの、しないもの
最近STYLY Sessionでは空間内のオブジェクトの動きが同期するようになりました。デフォルトで同期するので、同期対象を理解して制作しましょう。
* EventTrigger
    * Webのマウスクリックなど同期します
* STYLY InteractionSDK
    * InteractionSDKはすべて同期します
    * STYLY StudioのModifireにもInteractionSDKのものがあるが、これも同期する
* uGUI
    * 一通り同期されます。

注意が必要なのはこの辺です
* PlayMaker
    * PlayMakerでEventTriggerなど同期イベント起因でない状態変化を実装をするとズレます
    * Waitで数秒後、という実装をしてもずれるつもりでいましょう。
* Rigidbody
    * 常時同期するというより、InteractionSDKなど起因で発生したベクトルの変化が同期する感じです。
    * なので玉転がしゲーム的な厳格な位置が求められるときはトリッキーな実装が求められるでしょう。


この辺の詳細はこの[ドキュメント](https://document.styly.cc/doc/docs/en/creator/creator_sync_interaction/)を参照してください

## 途中入場に対応する
上記のドキュメントにも記載されていますが、途中入場した場合、これまでの動機内容は共有されないのでズレます。運用として途中入場者が発生したら該当シーンを読み込みなおす必要性があります。余裕がある場合は、同期対象の状態を復元する実装をPlayMakerで実装することはできますがおすすめしません(一度やってみたら大変だった。やったのはuGUIのInputFieldでOnChangeを発生させて、Textで同期モノの最新位置を共有するようななにかです。)

## 現在時刻を表示する
イベント中、気がついたら時間が経ってしまった、ということはよくあります。VR空間内のホストが見やすいところに時計を設置すると捗ります。そうでなければ別途外部でタイムキーパーを用意するしかないです。簡単なものでもいいのでしっかり準備しましょう。

## Sessionのホストにアバターを着せたくなった場合
複数人で体験する場合、特に説明をするようなイベントの場合はホストが目につく方が良い体験になります。実はSTYLY　Sessionでホストにアバターを着せる方法があります。[STYLY Pro](https://styly.cc/ja/pro/)の契約をしてやり方を聞いてみてください。(ステマ)

# おわりに
如何でしたでしょか。全デバイス対応STYLYシーンを作るイメージはできましたか。プロジェクトターゲット次第では全デバイス対応という山を登る意味はあります。この記事がその大いなる選択の一助になれば幸いです。

もしも不安に思うことがあれば私がお力添えできるかもしれません。[私のX](https://twitter.com/noria901)にDMでご相談ください。