VRChatでUDONエアホッケーを作ってみた話 3
前回の続きです。承前。
Synchronize Positionでは上手くいかなかったので違う方法を考えます。
(案2)外圧が加わるタイミングで位置と勢いを同期
ゲームの性質上、力が加わるのはplayerがMalletでPuckを打った時に限定されるので、その時に位置(Position)と勢い(Velocity)を同期することにしました。
「環境が同じなら、同じ位置で同じ力を加えれば同じ動きをするだろう」という発想です。
この方法だとPuckは非同期オブジェクトになります。自動的に同期はせず、自分で作った同期変数を直接監視して、アップデートがあればPuckのPositionとVelocityを更新します。
幸いにしてVRC物理の壁が立ちはだかることも無く、無事に良い感じの動きが作れたのでこれを基本方針にしたいと思います。
ここからは課題に対処していきます。
(課題1)遅延の壁
当然VRChatはネット回線の向こうの世界なので遅延は避けられません。
Player(アバター)がゲーム内に存在して、既に遅延の影響を受けているのでゲームスピードを直接コントロールする(待ち合わせをしてから動かす)事も出来ないと考えました。
現状の方式だと具体的には攻撃側から少し遅れて追従する動きを取ります。
こればかりはどうしようもないので究極の選択を迫られます。
1. 攻撃側優先:守備側は防御した時既に失点している
2. 守備側優先:攻撃側は明らかにゴールに入ったのに後から防がれる
ここはゲーム性を考慮して2を選択します。不可解な得点は受容し、理不尽な失点を避けましょう。とは言っても幻のゴールも防ぎたい。
幻のゴールを防ぎつつ守備側(青)を優先するという事は、青世界でのゴールを得点にしつつ、赤世界で先行ゴールすることを避ける必要があります。そのためには、最後にPuckに触った攻撃側(赤)から青に”基準世界”を移す必要があります。(なんかJOJOっぽい話になってきたな)
基準世界を移行するチャンスは大きく3種類。
1.赤がPuckに触れたとき:何回触れるか分からないのでボツ
※テニスのようなワンタッチ制限ルールがあれば採用できる
2.青がPuckに触れたとき:手遅れなのでボツ
3.赤エリアから青エリアに移動したとき:採用
というわけで自陣から相手陣地に移動する時に世界の壁を越える作戦で行きましょう。
その際に同期待ち時間が必ず発生するので、これはもうエフェクトを付けて「そういう演出」って事にしてしまいます。
で、出来上がったの以下のプログラムです。
ぱっと見よくわからないけど自陣から相手側に行く時だけ待ち合わせ(渦巻演出)が発生してますね。
何故そうなるのか、全体の流れの説明は次回へ続きます。