バーチャル展示会をSDK3に移行するために必要なこと
皆さんお疲れ様です。hatsucaです。
Vket6が終わり、ようやく人心地がついた今日この頃。
いかがお過ごしでしょうか。
今回は、ある意味前回のVket5から最も変わった点とも言える、
SDK2からSDK3への全面移行について書いていこうと思います。
SDK2とSDK3は何が違うの?
SDK2ではトリガーとアクションという簡易な仕組みでワールドギミックを構築します。
出来ることは少ないですが、直感的で分かりやすいです。
それに対してSDK3はUdonという、VRChatが独自で開発したプログラミング言語を用いてワールドギミックを構築します。
出来ることは非常に多いのですが、複雑であり、扱うには基本的にプログラミングの知識が必要です。
正直なところを言えば、大半の出展者はUdonを必要としていないでしょう。
Udonの入稿をUdonSharp(*1)に依るもののみに限定したせいもあるでしょうが、Vket6において自作のUdonを入稿した出展者は全体の15%程度でした。
(*1 Merlin氏によるUdonをC#風に記述できるコンパイラ)
しかしSDK2は後方互換のために残されているものであり、公式のドキュメントにおいても非推奨とされています。
今後のサポートも考えるといつかはSDK3に移行する必要があるのです。
SDK3に移行するうえでの問題点
SDK2からSDK3に移行するうえで問題となる点が二つあります。
一つは、Udonをプログラマー以外が扱うのは難しいという点。
もう一つは、Udonの自由度が高すぎるという点です。
順に説明していきましょう。
Udonをプログラマー以外が扱うのは難しい
VRChatはUdonを構築するためにUdonNodeGraphというビジュアルスクリプティングツールを用意しています。
しかし、これを扱うには最低限のプログラミングの知識が必要であり、
SDK2のように全く知識無しで扱えるようなものではありません。
現在最も高いシェアを持っているコンパイラであるUdonSharpも当然C#の知識が必要です。
前述の通り、大半の出展者は複雑なギミックを組みたいとは思ってはいませんが、
ちょっとした物を作るのにもプログラミングを学ぶ必要があるという状態は
出展者の取れる選択肢を狭めてしまう可能性があると思います。
Udonの自由度が高すぎる
移行の最大の障壁がこれです。
とにかくUdonは自由度が高すぎるのです。
スクリプトの組み方によっては容易にインスタンスを落としたり、
多大な負荷を掛けることが出来てしまいます。
インスタンスが即落ちたりするのであれば、
原因のブースを探して撤去するだけで済むのですが、
複数のブースでの負荷が累積することによってパフォーマンスの低下が生じている場合は原因の特定が困難です。
複数のブースを同じワールドに置く以上、一つのブースが他のブースに与える影響は最小にしなければならないのです。
問題の解決のために - UdonCube -
上記の問題を解決するための試みをVket5から始めました。
UdonCubeがそれに当たります。
UdonCubeでは常に一つのブースのみが表示されます。
それを利用して表示されていないブースを非Activeにしておくことで、
ブースが他のブースに影響を与える問題を解決しようとしました。
また、同時にUdon規定を制定し、
インスタンスに大きな影響を与える関数等を制限しました。
結果としては、表面上は上手くいきましたが課題が残りました。
この方法は常に一つのブースしか表示されない状況でしか使えないですし、ブースを非Activeにすることによって、ワールドに後から入るプレイヤーに対して同期処理を行うことができないという問題がありました。
そしてUdonの敷居の高さは解消できていないままでした。
Vket6に向けて
Vket5が終わった後、上記の課題を踏まえた新しいUdonの扱い方を、Vket6に向けて考え始めました。
まず、Udonをプログラマー以外が扱うのは難しいという問題ですが、
これはもうUdonコンパイラを自作した方が早いという結論に達しました。
私が求めていたのはSDK2のように、
Udonのごく限られた機能のみを実装したものだったので(複雑なものならUdonSharpで書けばいいので)、
ごく限られた機能ならば自分で作ることも出来るのではと考えたのです。
4月頭から作り始め、6月ごろには形になりました。
GameObjectのActive切り替えと、
Animatorのパラメータ変更程度しか出来ない簡素なものでしたが、
5%ほどの出展者に使ってもらえたようで良かったのかなと思います。
Udonを制御するために
さて最大の問題である、Udonの自由度が高すぎるについてですが、
皆さんはUnityのスクリプトライフサイクルというものをご存じでしょうか。
Unityはゲームの実行中、常に処理を回し続け、適切なタイミングでユーザーのスクリプトの処理を実行します。
この際、非Activeなオブジェクトの処理は実行されません。
この仕組みが出展者のUdonの制御にも使えるのではないかと考えました。
高い負荷が発生する原因のほとんどは、Update関数などの毎フレーム処理が呼ばれる場所で重い処理を行うことによります。
なのでVket6のUdon規定では毎フレーム処理が呼ばれる関数を禁止し、
その代替としてVketUpdateなどのオリジナルの関数を定義しました。
そして、ワールドにVketUdonManagerという管理用のUdonを用意し、プレイヤーがそのブースの近くにいる時だけオリジナルの関数を呼び出します。
こうすることでブースを非Activeにすることなく、常に一つのブースだけが継続的に処理を行えるようになりました。
この試みによって、Vket6ではUdonの自由度を最低限保ちつつ、負荷の問題をある程度クリアできたんじゃないかな、と思っています。
ただ、下見期間中に出展者のUdonが機能しなくなる事が何度かありました。
その度管理用Udonの修正を行ったりなどで、ご迷惑をお掛けしたことをここにお詫び申し上げます。
さらなる課題
私はこの制御方法が完全なものだとは思っていません。
Udonにおいて、他のUdonBehaviourの関数を呼ぶ行為はそれ自体がコストになります(全てのブースで処理が走り続けるよりはましですが)。
また、使用不可の関数や制限も多く、まだまだ出展者が商品そのものに近い形で出展を行えるようにはできていないと思います。
出展者の方々が持つそれぞれの魅力を、バーチャル展示会という場で最大限発揮できるようにするためにはまだまだ沢山の課題があります。
Vket単体だけでなく、コミュニティ全体でこの課題を乗り越えていけたらと、私は願っています。