SabaProps

拡充ロードマップ

0.2.0 まではローカル専用のカメラリグです。ここでは、これを複数カメラの
スイッチャーまで広げるまでの計画と、その過程で決めた線引きを記録します。

計画は 1 つの PR にまとめず、下の表の単位で切ります。1 PR あたりの検証範囲を
Unity 無しのオフライン検査で押さえられる大きさに保つためです。

マイルストーン

版内容状態
0.1.0単一カメラ、ローカル、追従・自動カメラワーク・自動フレーミング・Pickup 補正完了
0.2.0ローカル操作用 Canvas、外部 UI 向けの対象指定 API、2 台構成のデモシーン完了
0.3.0同期(オペレータが操作し、全員が同じ画を見る)未着手
0.4.0Inspector とサンプルシーン未着手
0.5.0据え置きカメラ(ドリー・タレット)未着手
0.6.0複数カメラとスイッチャー未着手
0.7.0自動ターゲット切替未着手

同期を Inspector より先に置いているのは手戻りを避けるためです。同期を入れると
どのフィールドがオペレータのものでどれが各自のものかが決まり、Inspector の
出し分けはそれに従います。逆順にすると Inspector を 2 回書くことになります。

0.3.0 同期

同期するのは Transform ではなくパラメータです。理由は
design.md に書いたとおりで、帯域と滑らかさの両方でパラメータ配布が
勝ちます。

BehaviourSyncMode は Manual にします。追従の状態はオペレータが触ったときにしか
変わらず、変わらない間は 1 バイトも流す理由がありません。

同期する変数型
対象の playerIdint
部位byte
追従モードbyte
方位・仰角・距離float
方位トリム・仰角トリムfloat
画面占有率float

Pickup 補正の扱いが問題になります。掴んでいる間の姿勢は毎フレーム変わるため、
そのまま同期すると Manual sync の意味がなくなります。掴んでいる間は 10 Hz 程度に
間引いて RequestSerialization を呼び、離した時点で 1 回確定させます。
オーナーシップは Pickup が自動で移すので、リグ側でやることは
Networking.IsOwner による書き込みの遮断だけです。

ローカルモードは残します。同じスクリプトの「パラメータの供給元を切り替える」だけで
両立できます。オペレータの画とは別に、自分の見たい人を追いたいという要求は
別のものです。

この層は自動検査できません。 ClientSim はローカルプレイヤーしか生成しないため、
同期の伝播もオーナーシップの移動も再現できません。オフライン層で押さえられるのは
「どのパラメータからも同じ姿勢が解けること」までで、実際に届くかは実機で確かめます。
検査できないことは README に明記します。

0.4.0 Inspector

0.1.0 のフィールドは int 定数で部位と追従モードを指定します。数値を覚えて
入力させるのは実用に耐えないので、Inspector で列挙に落とします。

同時に、追従モードによって意味のないフィールドが出ています。ワールド基準の軌道では
被写体の向きは使わず、自動フレーミングが有効なら距離は表示するだけです。
出し分けます。

サンプルシーン生成は 0.1.0 に前倒ししました。ステージ・スクリーン・2 台のリグ・
Pickup・VRCSceneDescriptor を生成します。メニューと確認手順は README を参照してください。

RenderTexture はバイナリアセットです。Foliage がテクスチャを持たない方針を取ったのと
同じ理由で、リポジトリには置かず、サンプルシーン生成時に AssetDatabase へ書き出します。

0.5.0 据え置きカメラ

0.1.0 の追従は「被写体を中心とする球面上にカメラを置く」1 つのモデルだけです。
ステージには据え置きのカメラも要ります。

モード位置向き
ドリー被写体に追従ワールド固定
タレットワールド固定被写体を注視

どちらも既存のパラメータ表現に載ります。タレットの注視は、任意の位置から
BakeYaw / BakePitch で方位と仰角を求めて AimRotation に渡すだけで、
0.1.0 のコードがそのまま使えます。ドリーは軌道位置と固定回転の組み合わせです。

0.1.0 に入れなかったのは、どちらも検査経路が増えるのに対して、
「演者を追い続ける」という当初の要求には軌道の 2 モードで足りるためです。

0.6.0 複数カメラとスイッチャー

複数のリグを 1 つの出力へまとめます。スイッチャーが持つのは「いまどのリグを
プログラムに出すか」だけで、リグ自体は独立して動き続けます。

RenderTexture を 1 枚にして描画するカメラを切り替えるか、カメラごとに
RenderTexture を持ってマテリアル側で切り替えるかは、負荷を測ってから決めます。
前者は稼働カメラが常に 1 台で済みますが、切り替えの瞬間に 1 フレーム抜けます。

同時稼働台数の上限は設定で持たせます。リアルタイムカメラは重く、
これを制限しないパッケージは重いワールドを作る道具になります。

0.7.0 自動ターゲット切替

複数の演者の間でターゲットを自動的に切り替えます。切替のトリガをどう取るかが
本体で、候補は次のとおりです。

  • ステージ上のゾーンへの侵入
  • 移動量(動いている人へ寄る)
  • オペレータが指定した優先度
  • 一定時間ごとのローテーション

発話量は使えません。Udon から他人の音量を読む手段はありません。

切替は「カットする」か「回り込む」かの 2 通りがあり、後者は 0.1.0 の
カメラワークの機構をそのまま流用できます。位相を進める代わりに、
新しいターゲットへ向けて 1 回だけイージングを走らせます。

やらないこと

視点そのものを移すカメラ。 VRChat のワールドがプレイヤーの視点を奪う手段は
ありません。出力先は RenderTexture のスクリーンだけです。

他人のアバターのパラメータやカスタムボーンの参照。 Udon から取れるのは
Humanoid のボーンとトラッキングデータだけです。