BlenderとUnityではじめてのQuest対応VRChatワールド作り_技術編

#はじめに
制作にあたって、たましこさんの記事を主に参照しました。とても助かりました。

>UnityのUの字もわからないレベルから始めるVRChatのワールド作り(基本編)
https://qiita.com/tamsco274/items/f8fb52eafe012a40e76f

>UnityのUの字もわからないレベルから始めるVRChatのワールド作り(応用編)
https://qiita.com/tamsco274/items/dfb66e8770b6ed65d025


わたしのこのページは、上記の基本知識を読んでもわからなかったこと、クロスプラットフォームに対応する上で調べたことなどを、備忘録的に残すことを目的としています。BlenderもUnityもわからないまま調べながらやっているので、間違っているところがあったら申し訳ないです。指摘していただけるとありがたいです。

思想編にも書きましたが、とにかく軽いワールドを目指しました。2020/9/18時点で349.47 KBです。
>BlenderとUnityではじめてのQuest対応VRChatワールド作り_思想編

>https://note.com/masaki_nire/n/n83d79931783e

#ワールド概要
![ワールド情報.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/727540/0c7d7ca0-9134-a68a-b097-90ddd6c23014.jpeg)

あるもの（設定したこと）

- 床、壁、屋根（コライダー）
- スカイボックス（画像1枚から作成）
- 光源（ベイク）
- イベントカレンダー（boothで入手）
- ミラー（スイッチでON OFFトグル）
- 持てる星（ピックアップ）




#モデリング
ソフトはblenderを使用しました。
Floor、Pillar、ScreenColliderの3つのオブジェクトに分かれています。円柱と直方体の組み合わせでできています。
円形に並んだ柱はCylinderの側面ポリゴンを等間隔で残し、ソリッド化モディファイアを使用し厚みをつけました。変形の際はこの等間隔の並びが崩れないように気を付けます。

![blender03.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/727540/4d507134-5988-ffc0-115f-b59b08e7000d.jpeg)
スクリーンと屋根が一体になっていて、その上に立てるようにします。コライダー用に隙間部分のオブジェクトも作ります。あとでunityで見た目だけ消すことができます。

UV展開はunityでのベイクに響くので、少し手を加えます。ピクセルに対し斜めだと影にジャギーが入るので、TexToolsで形を整えます。
![PillarUV00.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/727540/69793e90-37ce-0860-1e11-9ed9be5504ac.jpeg)


小さいテクスチャ2枚より大きいテクスチャ1枚のほうが軽いと言われていますが、技術不足で2枚になりました（正確にはテクスチャはFloorの1枚だけ。Pillarはマテリアルで色をつけるのでジャギーだけ気を付ける）。
テクスチャ画像はaffinity designerで作製しました。jpgで1024*1024*24BPP(RGB)　解像度は72dpi、90.78KBです。

![blender04.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/727540/18d3ffff-373f-1bb7-0ddc-2ed6a7210b2b.jpeg)
ワールドに置くものも作ります。

![blender02.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/727540/5c030bcb-250d-94f1-cba5-9cbf084ac831.jpeg)
fbxでエクスポートします。なんとなく「すべてFBX」にします。


#unity
###準備
まずquest、その次にPCの順で作成します。プロジェクトは分けたほうが管理しやすいです。あとから複製もできます。
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">VRChatでQuest対応ワールドを作る時の注意点！<br>SDKのAndroid用にアップロードする機能を使うと<br>Questから見たとき左右の目の視界が大きくズレてしまうという完全に初見殺しの罠があります！<br><br>必ずBuild SettingsでSwitch Platformでプラットフォームを<br>切り替えてアップロードしましょう <a href="https://t.co/khzPw4wIZ5">pic.twitter.com/khzPw4wIZ5</a></p>&mdash; ウミウシヲ / UMIUSiO (@UMIUSiO) <a href="https://twitter.com/UMIUSiO/status/1306919933704462338?ref_src=twsrc%5Etfw">September 18, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
![unity01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/727540/65c2f8b3-c7e0-943f-c718-d60045ea1a87.jpeg)
新規プロジェクトを作製、VRChat公式サイトからダウンロードしたVRCSDK2をインポートし、Ctrl+Shift+Bでプラットフォームを切り替えます。

![unity02.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/727540/b91599b2-b2c6-e28c-4645-a6fc992b01f4.jpeg)
タイトルバーに今のプラットフォームが表示されるので、適宜確認します。

![unity03.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/727540/a9d4429a-7317-3c8e-96a1-3feaaba8c444.jpeg)
[Window][Rendering][Lighting Settings]でウィンドウを出し、Inspectorのところに置きます。下部分にあるAuto Generateのチェックを外します。
これは影の計算（ベイク）をなにか動かすたびに自動でするか、やりたいタイミングで手動でやるかということです。ベイクは負荷と時間がかかるため、手動のほうがよいでしょう。

###各種インポート
作ったfbxをインポートし、マテリアル・テクスチャを設定します。
VRChatにはjoinした人がワールドの原点に一瞬表示されるバグ（？）があります。これはunity上の0,0,0の地点です。このワールドでは図の地点を0,0,0に合わせています。
![unity04.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/727540/1be81a36-b5c8-562b-f519-e59b3d249539.jpeg)

VRCWorldを設置します。これを置くことで、このプロジェクトは（アバターではなく）ワールドであると認識してもらえます。
![unity05.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/727540/43f1231e-2059-690e-f890-9bc0c107d913.jpeg)
左上の囲った部分がLocalになっていることを確認してください。
Z（青い矢印）方向を向いてスポーンします。めり込まないよう、床から少し浮かせます。

イベントカレンダー等も設置します。それぞれのReadMeを必ず読んで、規約や指示に従ってください。

###コライダー
床、壁、屋根に衝突判定を付与します。こうすることで床に立てるようになります。
[Add Component][Physics]より[MeshCollider]を選びます。
![unity06.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/727540/c0e3ccae-5623-fea2-6708-c8fb9cf09b65.jpeg)
コライダーは主にMeshColliderとBoxColliderがあります。Meshはメッシュの形通りに衝突判定が付与されます。ポリゴンが多いと重いらしいです。
Boxは自分で変形させて設置します。軽いらしいですが変形に苦労したので今回は使用しませんでした。
![unity07.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/727540/61911d7f-ecd6-c07c-f432-6662282d8f1e.jpeg)
透明部分にもMeshColliderを設定し、Mesh Rendererのチェックを外します。これで見えない床・壁になります。

###スカイボックス
![skybox.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/727540/d414c4d3-03db-7290-0bd6-c52f5c3395f2.jpeg)
affinity designerでこういう画像を作製。jpgで512*512*24BPP(RGB)　解像度は72dpi、13.75KBです。
以下の記事を参考にしました。

>UnityのSkyboxのテクスチャを自作する
https://bibinbaleo.hatenablog.com/entry/2019/08/12/220032

skyboxの色はベイクに響きます。それ自体の色より全体との調和をみたほうがいいかもしれません。

###ライト・ベイク
![unity08.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/727540/0827fc09-a729-7f42-1b93-7dcad066966e.jpeg)
床や柱、カレンダー等の動かないものはStaticにチェックを入れます。
このワールドではDirectional Light 1個のみ使用。以下のように設定しています。
![unity09.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/727540/5912b1ae-34db-aa7f-9f6d-4f1d862db753.jpeg)![unity10.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/727540/c735aeb7-2f27-702c-a32b-5a668d63bacc.jpeg)
static物の設定が終わったらInspectorの「Generate Lighting」でベイクします。
ベイク後にstatic物を動かしたりライトの設定を変えても、影はベイクした状態で固定されているので、都度ベイクしていきます。


###ミラー
たましこさんの記事を参考にしました。この通り作っただけなので解説できません。
最初は非表示で、スイッチを入れるとON・OFFのトグルができるよう設定します。
>https://qiita.com/tamsco274/items/dfb66e8770b6ed65d025#%E9%8F%A1%E3%82%92%E3%83%9C%E3%82%BF%E3%83%B3%E3%81%A7%E3%82%AA%E3%83%B3%E3%82%AA%E3%83%95%E3%81%A7%E3%81%8D%E3%82%8B%E3%82%88%E3%81%86%E3%81%AB%E3%81%99%E3%82%8B


###ピックアップ
まず1個だけアイテムを置き、Add Componentで「CapsuleCollider」「VRC_Pickup」「VRC_ObjectSync」を付与します。
「CapsuleCollider」はEdit Colliderで大きさを調整します。
![unity11.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/727540/eacbeadf-fcfb-82f7-7040-874ccb8c2b6c.jpeg)
VRC_Pickupを設定すると自動的に「Rigidbody」も付与されます。
今回は空中に浮いたままにしたいのでUse Gravityはチェックを外し、Is Kinematicにチェックを入れます。
持てる距離をProximityで変更します。

VRC_Pickupを付与するとオブジェクトのレイヤーが自動的にPickupに切り変わる、という話がありますが、Android環境ではそうなりませんでした。これは自分で追加することができます。
![unity12.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/727540/30aa72ce-c6b5-c0a9-568c-a04fc0402926.jpeg)
メニューバー[Edit]→[Projet Settings]の[Tags and Layers]で設定します。PC環境に合わせてUser Layer13にPickupレイヤーを設定しました。

VRC_ObjectSyncは位置の同期のために入れます。

マテリアルを設定し、Ctrl+Dで複製します。1個ずつ4色作ったら、それぞれ11個増やします。
10°ずつ回転の幅を増やし、ランダム性を持たせます。そしていい感じに散らします。

###重力・落下・ジャンプなど
![unity13.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/727540/3a7e0268-4203-8b2b-60e2-486483540cd3.jpeg)
重力：[Edit]→[Projet Settings]の[Physics]で設定します。GravityのYを-9.8から-5に変更しました。

![unity14.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/727540/e112df3c-6e32-04ff-4c1e-642a96c05882.jpeg)
落下：VRCWorld（スポーン地点のやつ）の「VRC_Scene Descriptor」のRespawn Height Yを変更します。初期値-100はY-100になる（100メートル落下する）とリスポーンという意味です。これでは多いので-10とかにします。高低差があるワールドはこの限りではありません。

ジャンプ：VRCWorldに「VRC_Player Mods」を付与し、Add Modsでjumpを選びます。これでジャンプの高さを調整します。このワールドでは5にしています。Gravityと併せてテストしながら調整しましょう。

###声の減衰
![unity15.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/727540/26bda88f-1ac9-b86d-e494-b53e98395a3b.jpeg)
VRCWorldに「VRC_Player Audio Override」を付与します。
Gainが声の大きさ、Farが減衰距離です。
これは誰かとテストして調節しながら進めるのがいいと思います。


#プロジェクト複製
quest用プロジェクトを複製し、pc用プロジェクトを作ります。
**※unityを起動している際は終了させてください※**
**※必ずバックアップをとってから行ってください※**

①プロジェクトをフォルダごとコピー&ペーストする
②複製したフォルダの名前を変更する。
③フォルダ内の「（コピー元のプロジェクト名）.csproj」「（プロジェクト名）.Editor.csproj」「（プロジェクト名）.sln」を削除する
④unityを起動し、[open]から複製したフォルダを開く

削除した3ファイルは新しいプロジェクト名で自動的に作られます。
pc用にシェーダーを設定しなおします。カレンダーもPC用を置きます。


#ワールドテスト（Local）
[VRChat SDK]→[Show Control Panel]の[Builder]Build & Testより、VR環境でのテストができます。
アップロードはしないため、他の人を呼ぶことはできません。カメラを使えるため、気になった箇所は写真に残しておくと直し洩れを防げます。

#アップロード
[VRChat SDK]→[Show Control Panel]の[Builder]Build & Publish for Windows(Android)よりアップロードできます。
![unity16.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/727540/9c0caf87-a1be-2a93-1d2e-a708cf85db46.jpeg)
①ワールド名、②最大人数、③ワールドの説明、④サムネイルを設定します。
③ではワールドにR18要素、NSFW要素が含まれている場合、必ずチェックを入れてください。

![unity17.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/727540/1eb82ee6-6911-7b1a-b888-9a59b3237e0d.jpeg)
④サムネイルはHierarchyに増えたVRCCamを調節し見せたい面を選びます。
図の左上部分をSceneにすると視覚的にカメラを操作できます。画角も調節できます。

⑤VRChatの規約に違反していないことを確認し、チェックを入れます。
⑥にチェックを入れないと非公開ワールド（自分のみワールドを開くことができる）でアップロードされます。非公開ワールドはpublicでは開けず、招集範囲はfriend+ ～ inviteに制限されます。
後からVRChat公式サイトよりpublishすることができます。これがよくツイッターでみられる「コミュニティラボに上げる」ということです。こうすると他の人もワールドを開くことができるようになります。
一度publishしたあとも非公開ワールドに戻すことができます。

⑥にチェックを入れると、直接コミュニティラボにアップロードできます。


#ワールドテスト（Online）
まず自分でチェックし、ある程度の水準になったと思ったら次に他者からチェックしてもらいます。
クロスプラットフォームで作製した際は両環境からのチェックが必要です。わたしはQuestを持っていないため、ほかにQuestを持っている方にお願いしました。ここで問題がなければコミュニティラボに上げます。

テストは一人より複数人に見てもらうことをおすすめします。
複数人からの評価で平均的基準（声の大小、眩しいor暗いなど）が得られますし、自分では思いつかない点に指摘・評価をもらえたりします。


#おわりに
このくらいのワールドを作るのにこれだけの作業が必要です。そうしたらあのワールドとかこのワールドとかどうやって作られたのだろう、といろんなワールドに行くたび思うようになりました。
好きなワールドは写真を撮って、ワールド名を入れて「ここすき」とツイートしましょう。