VRChat Udon ではじめる VR 開発

この記事は Eureka Advent Calendar 2020 9日目の記事になります。

前回の記事は Web Frontend Team の Jon さんでAdventures in Web Modalsでした。

Web Frontend Team 所属エンジニアの竹内 ( a.k.a. BOXP ) です。

普段は日本版 Pairs の Frontend から Backend までを幅広く開発しておりますが、毎年 Web Frontend の記事を書き続けていて少しマンネリを感じてきましたので、このあたりでまったく関係のない記事を書いてやろうと思い立ち今回の Advent Calendar にも参加しました。

ですので、今回の記事は普段の弊社での業務とは一切関係のない内容であることをご理解頂いた上で読んで頂けますと幸いですmm

はじめに

弊社では直近の COVID-19 の感染拡大を受け、 2020 年 3 月頃からオフィスへの出社を制限し原則リモートワークでの勤務をしてきました。

その中で自分も例に漏れずリモートワークで勤務を続けてきましたが、外出する機会がぐっと減った事で、もともと持っていてたまに触る程度だった VR 機器を使う機会が一気に増えまして、 VR 機器を使ったイベント参加に飽き足らず会社のミーティングのサテライト会場のように VR プラットフォームを利用することすらありました。

VR 同人誌即売会を満喫中の著者( 2020 年8 月開催の ComicVket にて)

というわけで、今回はそんな自分が今最も利用している VR プラットフォームである VRChat についての紹介と、 VRChat 上に存在するプログラミング言語の VRChat Udon についての入門記事になります。極力 VR でよく使われる技術スタック ( Unity とか ) に明るくなくても理解できるような内容でまとめていますので、ぜひお試しください。

VRChat とはなにか

VRChat

VRChat は、ユーザーが自分でアバターや場所 (World) を作成してアップロードし、 VR 機器を使って利用する事ができる VR プラットフォームです。もし Second Life を知っているのであれば、 VR 機器に対応した Second Life だと思っていただければイメージしやすいかと思います。またこの種類のサービスとしては最も人気が高く、今年のハロウィンには同時接続数が 24,000 人を越えたとの発表がありました。 ( なお、 VRChat は Windows 専用ソフトなので今回の記事も Windows 向けの内容になります。)

さて、様々なものを自由に作って利用できる VRChat ですが、普段ソフトウェアエンジニアをしている自分としては一つどうしても物足りない点がありました。

VRChat は Unity へ専用の SDK を導入することでWorldやアバターのセットアップを行う事ができますが、セキュリティ上の理由から C# などを使ったプログラムや組み込みブラウザなどを含める事ができませんでした。 しかしそんな中で、今年の 4 月頃に公式からプログラミング言語の VRChat Udon が発表されたのでした。

VRChat Udon の登場により、 VRChat にアップロードする World でゲームなどの大規模なギミックを作りやすくなり、制作の幅が大きく広がったのです。(下の動画は VRChat Udon を使って作られたゲームの一例です)

VRChat Udon を使って作られた多人数参加ダンジョン攻略ゲーム ”Udon Sword”

ここから先では、実際に VRChat Udon を使って VRChat の World を制作するまでの知見を簡潔にまとめていきます。

VRChat Udon の基礎知識

VRChat Udon は現在 Alpha 版であり、頻繁にアップデートがなされています。利用する場合には今後大きく仕様が変化する可能性があることを十分にご理解ください。

VRChat Udon は、 VRChat に組み込まれた仮想マシンが bytecode を実行することでプログラムを実行する作りになっており、そのための独自アセンブリ言語である Udon Assembly と GUI でプログラミングが出来るノードベースプログラミング言語の VRChat Udon Node Graph が公式から提供されています。

VRChat Udon Node Graph

公式から推奨される VRChat Udon の使い方は VRChat Udon Node Graph を利用するものですが、アセンブリ言語の Udon Assembly は仕様がすべて公開されており、ユーザーが自由にコンパイラを作る事が可能になっています。現時点で既に Udon Assembly へのコンパイラは有志によって開発されており、最も有名なものとしては C# コンパイラの Udon Sharp があります。

これは主観的な意見ですが、普段プログラミングに馴れているのであれば VRChat Udon Node Graph よりも Udon Sharp を用いた方が容易にプログラムを組めますので、この記事では Udon Sharp を使用する方向で話を進めていきます。

VRChat の World を作る

VRChat Udon に触れる前に、まずは VRChat Udon なしの World を VRChat へ アップロードするまでの手順を紹介します。

必要なソフトウェアの導入

まずは必要なソフトウェアをインストールする必要があります、 Unity Hub ・ VRChat の2つをインストールしましょう。なおVRChat は Steam を通して配布されているため、 Steam を先に導入する必要があります。( Unity Hub ではなく直接 Unity をインストールすることもできますが、 VRChat の推奨バージョンが変化することがあるので複数のバージョンの Unity を管理できる Unity Hub を推奨しています。)

またSteam から VRChat を導入できたら、 VRChat の公式ページでユーザー登録を済ませておきましょう。

VRChat 新規登録ページ : https://vrchat.com/home/register

Unity プロジェクトの準備

必要なソフトウェアが準備できたところで、 VRChat の World を作るために Unity プロジェクトを準備します。

まずは VRChat から推奨されているバージョンの Unity を Unity Hub へ導入しておきましょう、 下のページで “Click here to install the current version of Unity via Unity Hub.” をクリックする事で Unity Hub へのインストールが可能です。

Unity のインストールが完了したら、 Unity Hub からプロジェクトを作成します。下の画像を参考に Unity のバージョン選択を開き、先程導入したバージョンを選択してください。 (2020/12/08 時点では 2018.4.20f1 です )

新規作成ボタン横の▽から Unity のバージョンを選択できます

バージョン選択後は表示される画面に従ってプロジェクト名を入力し、プロジェクトを作成してください。

続いて、 VRChat のコンテンツ作成に必要な SDK をプロジェクトへ導入します。 VRChat SDK は VRChat の公式サイトで配布されているためログイン後に「Download」ページから SDK をダウンロードします。 VRChat SDK2 と VRChat SDK3 の2つがありますが、 VRChat Udon を利用する場合は VRChat SDK3 の方をダウンロードする必要があるため注意してください。

VRChat 公式ページ : https://vrchat.com

左側のDownloadページからこのページが開く

ダウンロードした SDK(.unitypackage ファイル ) を、先程作成したプロジェクトのウィンドウへ ドラッグ&ドロップすれば SDK の導入は完了です。

SDK のファイルをプロジェクトの「 Assets 」へドラッグ&ドロップ

ドラッグ&ドロップ後、確認のダイアログが表示されますがそのまま Import をクリックして先へ進めればOKです。

最後に、VRChat SDK から VRChat へのログインが必要なのでログインさせておきます。

プロジェクト一番上のメニューから「 VRChat SDK 」→「 Show Control Panel 」を選択するとログインフォームが表示されるためここからログインしてください。

VRChat へのログインフォーム

これで World を製作するための準備はすべて完了です。

World の作成とアップロード

準備が整ったところで、簡単な World を作ってアップロードしてみます。

まずは最低限ユーザーが立つことができる床を設置しましょう。

床になるオブジェクトを設置するためには、先程作成した Unity プロジェクトのウィンドウのうち、「 Hierarchy 」と書かれているタブで床になるオブジェクトを追加します。タブの何もない所で右クリックをし、「 3D Object 」→「 Plane 」を左クリックして追加します。

Hierarchy に Plane オブジェクトを追加

Plane オブジェクトを追加すると、右側の画面に薄く平たい板が配置されているはずです(もしよく見えない場合は、マウスホイールを回転させてカメラの距離を調整してみてください)。今回はこれを床として利用します。

追加された薄い板

床の追加が終わったら、この床だけの場所が VRChat World である事を示すために必要なオブジェクトを追加します。このオブジェクトは VRChat SDK の中に同梱されているため、 SDK のフォルダの中から持って来ましょう。

Unity に追加された VRChat SDK のフォルダの中を見るには、画面下の「 Project 」タブを確認します。タブに表示されている「 Assets 」フォルダを確認し、「 Assets 」→「 VRChat Examples」→「 Prefabs 」とフォルダ階層を下っていきます。すると「 Project 」タブの右側に「 Prefabs 」フォルダの内容が表示されます。

Prefabs フォルダの内容

このうちの「 VRCWorld 」を、先程床が設置された「 Hierarchy 」タブの何もない箇所へドラッグ&ドロップして追加します。「 Hierarchy 」タブの中に、「 VRCWorld 」が追加されていれば OK です。

VRCWorld 追加後の「 Hierarchy 」タブ

必要なオブジェクトの配置が終わったところで、 World をアップロードする作業に移ります。

World のアップロードは一度 VRChat へログインするときに表示した VRChat Control Panel から行います。表示するにはウィンドウ上部のメニューから「 VRChat SDK 」→「 Show Control Panel 」をクリックしましょう。

VRChat Control Panel の 「 Build 」画面で World のアップロードができます。

しかしまだ一度もアップロードを行っていない場合には以下のように注意が表示されます。この場合はそのまま 「 Setup Layers for VRChat 」をクリックすれば OK です。また「 Setup Layers for VRChat 」を実行後に Collision の設定を促されますが、そちらもそのままボタンをクリックして進めてください。

まだ一度もアップロードを行っていないときの Build 画面

すべての手順が終わると、以下のように Build 画面が表示されます。

準備完了後の Build 画面

この状態で「 Build & Test 」をクリックすると VRChatが立ち上がり、以下のように今作成した World を実際に試す事ができます。

作成した World のテスト画面、WASDキーで移動・マウス移動で視界移動ができます

World のテストができたらVRChat を終了し、 World のアップロードを申請しましょう。

※安全上の理由から、 VRChat には作ったばかりのアカウントからWorld やアバターなどのコンテンツをアップロードする事ができない仕組みが存在します。そのためこの後のアップロードの手順を行うためにはある程度 VRChat をプレイして信頼度を上げる必要があり、すぐには World をアップロードする事ができません。しかし、アップロードはできなくてもローカル環境での確認はできますので 作成したワールドを一人で遊ぶ事は可能です。詳細はこちらをご覧ください→ VRChat Safety and Trust System

World をアップロードするには、 VRChat Control Panel から「 Build & Publish for Windows 」をクリックし、 World の詳細を入力する画面へ移ります。以下のような画面が表示されるはずなので、必要な項目を入力してアップロードします。 ( 実際にはアップロード後には審査が入り、審査を通過後に初めて公開されます。ただし、 Publish to Community Labs にチェックを入れると試験中のワールドとしてすぐに公開されます。 )

World の詳細入力画面

これで VRChat の World をアップロードするまでの手順がすべて完了しました。ここからはついに VRChat Udon の導入へ進みます。

VRChat Udon & Udon Sharp を使った World を作る

初めて VRChat Udon を使った World を作るということで、本記事では簡単のため、 Udon Sharp の GitHub Repository でも最初のサンプルプログラムとして紹介されている「空中に浮いたキューブが回転している World 」を作成していきます。

UdonSharp に必要な追加パッケージをインストールする

まずは UdonSharp でプログラムを書くにあたって必要なパッケージを一つインストールします。 UdonSharp の GitHub レポジトリから最新のものをダウンロードしましょう。インストール方法は VRCSDK と同様で、ダウンロードした .unitypackage ファイルを Assets フォルダへドラッグ&ドロップします。

UdonSharp の GitHub レポジトリ : https://github.com/MerlinVR/UdonSharp/releases

回転させるキューブを配置する

パッケージのインストールが完了したら、続いて World へキューブを配置します。

以前床を配置したときと同じように、「 Hierarchy 」タブの何も表示されていないところを右クリックし、「 3D Object 」→「 Cube 」を左クリックして追加します。

Cube の追加
Cube 追加後の中央の画面だが、 Cube が床に埋まってしまっている

追加後に中央の画面に追加されたキューブが表示されているはずですが、表示されたキューブが床に対して大きすぎたり、または床の下に埋まっていたりしているかも知れません。空中に浮かんだキューブにするためには移動・回転・拡大 / 縮小させて調整する必要があります。

Cube などのオブジェクトを移動・回転・拡大 / 縮小させたい場合、画面左上のボタンから編集モードを切り替えた後、中央の画面でオブジェクトを引っ張って操作します。下の動画を参考にキューブを移動・縮小させてみてください。

Cube の移動 ( 矢印を引っ張って移動させる )
Cube の縮小 ( 真ん中の灰色の箱を下に引っ張って縮小させる )

宙に浮くキューブを配置できたところで、続いてキューブに回転を追加していきます。

UdonSharp でキューブを回転させる

UdonSharp に限らず、 VRChat Udon を World で実行するためには何かしらのオブジェクトに対して機能 ( Component )として 紐付けさせる事で初めて動作します。今回は先程配置したキューブに、自分自身を回転させる UdonSharp のコードを直接紐付けさせる事で回転させてみましょう。

オブジェクトに UdonSharp のコードを紐付けるためにはまず、対象のオブジェクトを選択して状態で画面の最も右側にある「 Inspector 」タブから操作を行います。

回転させたいキューブを「 Hierarchy 」でクリックして選択した状態で、一番右「 Inspector 」タブの「 Add Component 」ボタンをクリックします。するとテキスト入力欄が表示されるので、そこへ “Udon” と入力して追加する機能を絞り込みます。最後に絞り込んだ結果に表示されている「 Udon Behaviour 」を選択しましょう。

「 Add Component 」 ボタンは「 Inspector 」タブの一番下にある
「 Udon Behaviour 」を追加する

続いて、先程追加した「 Udon Behaviour 」に UdonSharp のスクリプトを登録させます。そのためには「 Udon Behaviour 」の中のセレクトボックスを「 Udon C# Program Asset 」に変更し、「 New Program 」をクリックします。

「 Udon C# Program Asset 」を選択し、画像にある「 New Program 」ボタンをクリックする

「 New Program 」ボタンをクリックすると、しばらく待たされた後に「 Create Script 」ボタンが表示されるためクリックし、 UdonSharp ソースコードのファイル名の入力を求められます。好きな名前で問題ないですが、今回は便宜上「 Cube.cs 」を指定しておきましょう。

さて、これでキューブと紐付けられた UdonSharpのソースコードが作成されたのでソースコードを編集します。ウィンドウ一番下の「 Project 」タブの「 Assets 」フォルダを選択すると、中に「 Cube.cs 」ファイルが配置されているはずですのでこれを好きなテキストエディタで編集しましょう。通常のファイラーと同様に「 Cube.cs 」をダブルクリックすればインストールされたエディタが立ち上がります。

「 Assets 」フォルダ下の「Cube.cs」をエディタで編集する

「 Cube.cs 」をエディタで確認すると、以下のように何もしないスクリプトになっている事がわかります。

using UdonSharp;
using UnityEngine;
using VRC.SDKBase;
using VRC.Udon;
public class Cube : UdonSharpBehaviour
{
void Start()
{

}
}

「 UdonSharpBehaviour#Start 」メソッドを定義する事で、Worldが生成されたときの処理を追加する事ができますが、今回は利用しないので代わりに画面再描画時の処理である「 UdonSharpBehaviour#Update 」に自分を回転させる処理を追加します。

using UdonSharp;
using UnityEngine;
using VRC.SDKBase;
using VRC.Udon;
public class Cube : UdonSharpBehaviour
{
void Update()
{
this.gameObject.transform.Rotate(Vector3.up, 90f * Time.deltaTime);
}
}

編集後ファイルを保存すると、 UdonSharp が自動で再コンパイルを実行してくれます。もしコンパイルが実行されていない様子であれば、Unity上で「 Compile All UdonSharp Programs 」ボタンをクリックする事で手動で再コンパイルさせることもできます。

さて、コンパイルが終わったら床だけの World をテストした際と同様に「 Build & Test」を実行してみましょう。すると…

宙に浮きながら回転するキューブの様子

やりました! これで初めての UdonSharp を使った World は無事に完成です。ここまで本当にお疲れ様でした!

おわりに

ここまでで VRChat についての軽い紹介と、 VRChat Udon & UdonSharp でキューブを回転させるプログラムを書く所までまとめました。

VRChat Udon は今回触れたようなオブジェクトを動かすだけでなく、 VR 機器を使ってトラッキングした手足の座標を読み込んだり、動画を読み込んで表示させたりなど Alpha 版ながら沢山の機能を持っています。より複雑な VRChat Udon を使った World を作りたい場合は、こちらにある UdonSharp の作者によるリンク集が役に立つと思うので是非ご確認ください

Community Resources · MerlinVR/UdonSharp Wiki: https://github.com/MerlinVR/UdonSharp/wiki/community-resources

それではまたどこかでお会いしましょう!

参考文献

Eureka Engineering

Learn about Eureka’s engineering efforts, product…

Eureka Engineering

Learn about Eureka’s engineering efforts, product developments and more.

BOXP(Keitaro Takeuchi)

Written by

Front-End Engineer at eureka, Inc. / Clojure / Go / TypeScript / https://boxp.tk / aka. BOXP

Eureka Engineering

Learn about Eureka’s engineering efforts, product developments and more.