見出し画像

バーチャルマーケット2023 Winter 制作記

Swishfです。12/2から12/17まで開催されるバーチャルマーケット2023 Winterに出展したのでブースの紹介と制作の流れを書こうと思います。

Butter Land

バターランド作りました!!!!!!!!!!

巨大バターが回す観覧車!!!!!!!!!!(乗れます!)

バターが全力で引っ張るジェットコースター!!!!!!!!(乗れます!)

かわいい!!!バターぬいぐるみ!!!!!!!!!!

組体操してるバター!!!!!!!!!!

なんかウェーブしてるバター!!!!!!!!!!

空飛ぶバター!!!!!!!!!!

ゲート裏のバター!!!!!!!!!!

こだわりポイント!!!!!

空を飛んでいるバターの黄色い風船にはバターの顔が描いてあります!
そして微妙に風船と体が揺れるようにボーンを入れてアニメーションを付けています!

ジェットコースターを引っ張るバターの足の動きの速さはジェットコースターのスピードと連動しています!

巨大バターの上にもぬいぐるみバターがあります!ジェットコースターに乗っているときに一瞬見えます!

敷地の関係で小さくせざるを得なかったバターランド、自分も小さくなることで存分に楽しむことができますが、そのサイズ変更はバターランドに入ったときに自動で行われます!出る時も自動で元のサイズに戻ります!

技術的な話!!!!!

データ配布

ブースのほぼそのままのデータを BOOTH に上げたのでよかったらダウンロードしてみてください!

何人でもアトラクションに乗れるように

Vketの出展制限

観覧車とジェットコースターはどの席に手を向けても Sit 判定が出現します。
しかし、今回の出展枠では椅子 (以下 VRC Station) の数は4つまで、ピックアップの数は5つまでの制限がありました。

椅子を常に自分の近くに配置する

本ブースでは5つのピックアップ (ローカル) が常に自分の近くの席に配置されるようにしています。
観覧車の近くに行けば自分と一番近い観覧車の席にピックアップが配置されます。ジェットコースターの近くに行けばピックアップはジェットコースターの近い席に配置されます。

全ての席に座れるようにピックアップを常に移動

これによってユーザーは常に自分に近い位置にある席に対してピックアップを行えるようになります。
あとはピックアップしたときに VRC Station もその位置に持ってきて座らせるようにしています。

椅子が足りなくなったら

VRC Station だけだと出展制限により4人までしか座ることができません。
そこで VRC Station が足りなければダミーの椅子を使用するようにしました。

ダミーの椅子は単純で、使用している間はプレイヤーをその席の位置に移動させるようにしています。
方法としてはローカルのプレイヤーに対して席の位置を目標座標としてプレイヤーの速度を調整しています。
これによってローカルでプレイヤーが席に追従し、他プレイヤーからは通常のプレイヤー位置同期と同じようにプレイヤーの位置が同期されて見えます。
(なぜテレポートを使わなかったのかは、テレポートは通信が発生し、速度変更であれば発生しないと思っていたためですが、未検証のため検証してみます)

PD制御で追従

欠点として、VRC Station であればプレイヤーの位置を同期せずに座っている VRC Station 情報だけ同期できるため、ローカルでプレイヤーの動きを滑らかに追従させることができるのですが、
今回の方法では通常の位置同期通り微妙にプレイヤーの位置がずれて表示されてしまいます。
また、適切に制御しなければ視界が揺れてしまいます。
プレイヤーの姿勢もそのままだと歩き状態になってしまいます。
Vket の制限内で展示する分には許容範囲かと思いこの方法にしました。

VRC Station と SetAvatarEyeHeight との組み合わせバグ

VRC Station に座った状態や座る前後で SetAvatarEyeHeightByMeters を行うとサイズ変更されず (戻らず) 意図しない挙動になることがあるのをVket入稿期限直前に知りました。
これは他のワールドで VRC Station に座った状態でデフォルトメニューからアバターサイズ変更を行っても発生するため本ブースに限ったものではありませんでした。

スケール変更して遊ぶ前提のためこのブースでその現象に出会ってしまうユーザーが多そうだと思い VRC Station を使用せずにダミー椅子のみ使用するように変更しました。

ジェットコースターの移動

コースの設定

ジェットコースターはコースとして設定したアンカーポイントに沿って移動します。移動速度は質量保存則に則った式で計算し、最大位置エネルギーは最も高いアンカーポイント+α で取得しています。

アンカーポイントの名前にIDを設定することでアンカーポイントに役割を持たせています。
役割は3つで、最初のゆっくりの移動 (外部の力によるけん引)、自由落下、ゴール前の減速それぞれが開始するポイントを設定しています。コースターがこのポイントを通過したときに挙動 (速度設定) が変わるようになっています。

これらの挙動にすることによって、スクリプト内で細かい設定をせずに Unity の Scene ビュー上でアンカーポイントを移動させるだけでコースを作れるようになってます。

滑らかに移動させる

移動はアンカーポイントから生成したベジェ曲線上を移動するようにしています。生成されるベジェ曲線を可視化するエディタ拡張も作成しました。(画像中の虹色のライン)

ベジェ曲線はパラメータ t (0~1) によってその曲線上の位置が定まります。
しかし、t が 0.1 であってもその曲線上の 1/10 の距離の箇所の位置を指す訳ではありません。 t が 0~1 で一定に変化してもその間の位置の変化にはむらがあります。
つまり、t を一定で変化させてもジェットコースターは場所によって加速したり減速したりする挙動になります。

これを回避するために、t が 0.1、0.2、…、1.0 それぞれの時の区間の距離 L を事前に算出しておき、コースターが X 進むときにその算出したテーブルから t の値を計算します。
これによってコースターを指定した速度で移動させることができます。

描画負荷を抑える

Vket には描画負荷を抑えるための制限もあります。
そのため巨大バターと観覧車や、ジェットコースターとそれを引っ張るバター、空を飛ぶ3体のバターはそれぞれ同じボーンでつないで1メッシュにしています。
結局制限に対してかなり余裕がある状態だったため後半追加した画像は特に負荷を考慮せずに配置していたりします。

アトラクションの同期

アトラクションとして滑らかに動作させつつ同期するにはテストの時間がなさそうだったので今回はネットワーク経由での同期を行いませんでした。

その代わりに端末時刻を基準にしてアトラクションが動作するようにしました。
観覧車は現在時刻の秒数によって回転角度を決めていて、ジェットコースターは毎分0秒で発車するようになっています。

これまで、この同期方法って VRChat においてどれくらいそれっぽく見えるのだろう、と気になっていたのですが今回試すことができて良かったです。当然条件によってはずれが大きいですが、小規模な展示でもしちょっとでも同期されていれば嬉しいかもという程度であればお手軽でそこそこ有効だなと思いました。

他にも追加したかった事

本来であれば園内をたくさんのバターの NPC が動き回り、一緒にアトラクションに並んだり乗ったり出来るようにして、1人で Vket を訪れても楽しめるようにしたいと思っていました。

他にはアトラクションやお土産店の充実や、ポップコーンやクレープを作ってくれるバター、ミニゲームなどを設置したかったです。

「OPEN in 2024」の看板と作業中のバター

Vket進捗どうですか集会!

毎回行われているVket進捗どうですか集会、今回も最後1回だけでしたが参加できました。
入稿期間中に毎週開かれているので出展者の方も出展に興味がある方も行ってみると良さそうです。

感想など

バター!

バターモデルライセンス

https://www.100avatars.com/

https://github.com/PolygonalMind/100Avatars/blob/master/CCLicense.md


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