見出し画像

ぶいちゃ感謝祭(5) ワールドとギミックのこと

私、Fujisawaは先日の2024年5月18日(土)、VRChatでのイベントとして「ぶいちゃ感謝祭」の主催行いました。イベントは大成功を収めることができたといっていいと自負しています。
イベントの様子はVRC放送局さんで生配信され、現在はYoutubeのアーカイブで見ることができます。

今回は、ぶいちゃ感謝祭で使用したワールドとギミックについて話していきたいと思います。ちょっと専門的な話も含みますので、ご了承下さい。前回の記事はこちらから


ワールドの「軽さ」

早速ですが、ワールドの「軽さ」について。
私の作成したワールドをご存じの方は、「軽さ」にこだわりがあって作成していることに、なんとなく気づいてらっしゃる方もいるかと思います。

2種類の「軽さ」

「軽さ」と一口に言っても、色んな種類の軽さがありますが、ここでは次の2種類について考えていきたいと思います。

  • ワールドの大きさ(サイズ)の「軽さ」

  • ワールドギミックの動作の「軽さ」

ワールドの大きさ

まず最初に、ぶいちゃ感謝祭のワールドサイズは、約14MBです。

現時点のワールドサイズ。14.09MB

しかも、この内のほとんどが音楽と画像とフォントに費やされているため、ワールド本体やギミックの大きさは3MBもないんじゃないでしょうか。

これらを実装するのにおそらく3MBくらい

テクスチャの数とライティング(光源)

ワールドでサイズが重くなる原因の一つはテクスチャです。
特に何も考えずにBake(光の当たり方を事前に計算してテクスチャで設定すること)を行うと、とんでもない量のテクスチャが生成されてサイズが重くなります。

弊ワールド、麻雀緑一色のBake結果。6枚の32x32のテクスチャなので12.2KBしかない

また、ライティング(光源)は増やせば増やすほど処理が重くなります。
ぶいちゃ感謝祭ワールドでは、ワールドに使用している基本テクスチャは2枚(ノーマルマップを入れれば3枚)、ライティング(光源)はDirectional Light(太陽光みたいなやつ)が1つのみで影の計算はなし。Bakeは行っていません。

ワールドに使ってるテクスチャ実はこれだけ
この辺、実は全部同じテクスチャなんです

ワールドの形

私の制作するワールドは、ほとんどQuad(壁)とCube(方体)で構成されています。実はUnityに最初から設定されているそれらのポリゴンは、いくら追加してもメッシュ(ポリゴン)情報が増えないためサイズが軽いという特徴があります。

上から見るとこんな感じ。なんじゃこりゃw

回答席も、軽いテーブルを作成し、Prefubと呼ばれる複数のオブジェクトをまとめて管理できる機能を使い、必要な数分並べます。こうすることで、70個の座席があっても、1席だけの情報量で構築できるわけですね。こうすることで、1箇所変えれば全部変わるので楽です。

回答席はPrefub化

では、その70席をどのようにしてまとめ上げるかについては、次のギミックの項目でお話します。

ワールドのギミック

複数の席を管理する

さて、ここからはさらに専門的な話になってきます。
先程のprefub内で、席で必要な設定は全て済ませておきます

prefub中に必要な設定は全て済ませておく

あとは、それらを管理するマネージャを作り、そのマネージャがすべての席を配列で把握できれるようにしています。

protected override void Start() {
    // これでseatsの中に、すべての席が配列として入る
    this.seats = this.playerSeatParent.GetComponentsInChildren<PlayerSeat>();
}

オブジェクトオーナーと言う考え

ワールドを作成したことのない方に簡単に説明しますと、同期するオブジェクト(もの)には「オブジェクトオーナー」が必ず存在します。
そして、同期させたい場合は必ずオブジェクトオーナーしか、同期させることができません。オブジェクトオーナー以外の人が同期させようとした場合、無視されます。
逆に言うと、同期するものの負荷はすべてオブジェクトオーナーにかかってくるということです。

オブジェクトオーナーの分散

弊ワールド麻雀緑一色では、麻雀卓が8卓あります。これらはすべて同期する必要があります。
オブジェクトオーナーは最初、最初にそのワールドに入った人に設定されています。つまり、8卓の麻雀卓の負荷を一気に受けることになるわけです。

すべての処理を行った上に、全員にその情報を送らないといけない。やばい

つまり、オブジェクトオーナーは適宜分散させる必要があるわけです。

「誰」に「どの」処理を任せるか

そこで考えなければいけないのは、誰にどの処理を任せるか。ということです。同期に必要なデータを抜粋すると以下のような感じになります。

  • 回答者データ

    • 得点

    • 回答番号

    • 回答時間

  • 問題文、解答文の文字列データ

この内、各回答者の回答番号と回答時間は、各回答者上で処理を行っています。
回答番号は各回答者で処理をしたほうがいいのは自明かと思いますが、回答時間については、今回の感謝祭の問題の出し方を鑑みると、回答者側で処理をしたほうがいいんですね。
なぜかというと、回答時間は回答者が問題を見てからボタンを押すまでの時間です。これは、それぞれローカルで測定したほうが都合がいいというわけです。

この処理ってローカルでできるね!

得点は全体の結果を元に計算するので、出題者がオブジェクトオーナーになっています。文字列データも出題者がオブジェクトオーナーがいいのは自明でしょう。
そして、これらは情報が切り替わったときにのみ同期を行うことで、全体的な負荷を下げています。

点数を同期していたタイミング。あまり頻繁に同期してないのがわかりますね

また、同期する必要がない情報や、同期した結果、ローカルで演算できるものはローカル演算で済ませていることもあります。これは、同期したほうが遥かに軽いという場合以外はそのようにしています。
基本的に、データのやり取りって重たいはずですし、出題者のみに負荷がかかる方法になってしまいますからね。そのあたりの取捨選択もワールドの軽さを考えるポイントかと思います。

カメラオブジェクト

ワールドには自分が見てるもの以外のものを映すことができるカメラオブジェクトが存在します。
このカメラオブジェクト、設置すればするほど重くなります
前回のnoteでも書きましたが、ぶいちゃ感謝祭では、様々な画角のカメラが存在します。また、各回答者に向かうカメラもありますので、使用している画角は100近くになります。
ですが、実際に使用しているカメラは常に2つだけです。回答者に情報を見せるメインウィンドウ用のカメラと、配信用のカメラになります。
使っていない画角のカメラはOFFにすることで、最低限の負荷を実現しています。

使ってるカメラは常に2つ

最後に

まとめると、ワールド作成時に考えていたことは次の4つですね。

  • テクスチャやライティングを多用しない(ワールドサイズと負荷軽減)

  • 誰にどの処理を任せるかを考える(処理負荷の分散)

  • 同期する回数を少なくする(データやり取りの軽減)

  • カメラは常に2つ(描画負荷軽減)

これらは、今まで作成したワールド「麻雀緑一色」と「V令和教育委員会」での経験があってこそですね。これら2つのワールドがなければこのイベントは生まれなかったんだろうなと思うと、感慨深いものがありますね。

それぞれのワールドのリンクは以下になりますので、よろしければ軽さを実感してみて下さい。


この記事が気に入ったらサポートをしてみませんか?