壁ツェーン

オンギャーの思考回路

VRChat Avatar Dynamics Contacts について

ついに VRChat の Open Beta に PhysBones が来たということで沸き立っていますが、ここであえてあまり話題に挙がっていない Contacts について説明しようと思います。

概要

Avatar Dynamics Contacts (以下 Contacts) は、自分や他人が触れたときに反応する部位を作ることができる機能です。 この機能は、 SDK 内では VRCContactSenderVRCContactReceiver というコンポーネントとして存在しています。

docs.vrchat.com

コンポーネント説明

というわけでまずは各コンポーネント自体について説明していきます。 英語が読める人は公式ドキュメントを読んだほうがいいと思います(爆)

共通: Root Transform Shape プロパティー

Sender/Receiver には、その形状として Sphere あるいは Capsule を指定することができます。

Root Transform は、指定しない場合 Sender がアタッチされているオブジェクトを基準として採用し、指定した場合はそのオブジェクトを基準として採用します。 生やしたいオブジェクトにしかアタッチできないとか、明示的に指定しないと動かないとかではなく、柔軟な指定ができてうれしいですね。

共通: Collision Tag プロパティー

Collision Tag は、干渉した相手に自分が何であるかを伝える・受け取る手段です。

例えばコンポーネントHead が設定されている場合、 Sender からは「自分は Head である」という情報を送信し、 Receiver は「Head である Sender のみ反応する」というような動作になります。 この Tag は複数指定することができ、 Receiver に複数指定した場合はそれらのどれか 1 つでも合致すれば反応するようになります。

VRCContactSender コンポーネント

Receiver に干渉するコンポーネントです。これが Receiver の検出範囲に入ることで干渉が成立します。

デフォルトでは頭部(Head)、胴体(Torso)、手のひら(Hand L/R)、足先(Torso)、そして各指(Index, Middle, Ring, Little L/R)に生成されます。これらは Avatar Descriptor で変更することが可能です(後述)。 また、この内手に関係するものは PhysBones のコライダーとしても利用されます。

このコンポーネントは、それらの部位以外の好きな場所に Sender をセットすることができるものです。例えばけもみみとか。 Collision Tag には標準のものの名前も設定できるようです。本来の部位とは別の部分を代わりに干渉させるみたいな芸当ができるのかもしれません。 とはいえ、基本的には Custom で使うことになると思います。

VRCContactReceiver コンポーネント

Sender による干渉を検出するコンポーネントです。 大抵の場合こちらを使うことになると思います。

  • Filtering
    • 検出対象の指定。
    • Allow Self: 自分自身の Sender の干渉を検出する。
    • Allow Others: 他人の Sender の干渉を検出する。
    • Local Only: ローカルでのみ検出する。つまり、他人から見えている自分では検出を無効にする。後述の synced Parameter で有用。
  • Receiver
    • 干渉を検出した際の出力の挙動の指定。
    • Receiver Type: 検出の挙動の種類を指定する。
      • Constant: Sender が範囲内にある間は Value の値を出力する。ない場合は 0.0 。
      • OnEnter: Sender が範囲内に入ったフレームだけValue の値を出力する。それ以外は 0.0 。
      • Proximity: 範囲の中央にどれだけ近いかを 0.0~1.0 の値で出力する。ない場合は 0.0 。複数ある場合は最も中央に近いものの値を出力する。
    • Parameter:
      • 値を出力する先の Animator Controller のパラメーターを指定する。型は Float でなければならない
      • ここで指定するパラメーターは Expressions Parameter で同期されるものである必要はない。 これは、ローカルとリモートでそれぞれ別個に処理されるから。
      • 同期されるものを指定する場合は上記の Local Only にチェックを入れることを推奨。
    • Value: Constant OnEnter の場合にパラメーターに出力する値を指定する。

Avatar Descriptor Colliders プロパティー

アバターに標準で生成される Sender 及び PhysBones Collider を設定できます。以下の説明では Collider で統一します。

Mirroed はデフォルトでチェックが入っています。外すと左右の別がある部位が別々の項目として出現します。

一般的な人型実体アバターの場合は Automatic のままでほぼ問題ありません。既存のボーンからちょうどいいサイズの Collider が生成されます。 また、不要な場合は Disabled を選択することで生成されないようになります。

Custom を選択した場合、基準となるボーンからの位置と回転、及びサイズが指定できるようになります。 基準となるボーン自体は変更できないため、他のボーンから生やしたい場合は自前で Sender を追加することになるでしょう。

用途

Receiver でパラメーターを操作できるので、それに応じて AnimatorController 側を組めば Expression Menu からやってたようなことは基本的に全部できると思います。 また、 PhysBones 側でオプションで生成される Grabbed パラメーターを応用するテクニック等もあるようなので、インタラクティブアバターがじわじわ流行ってくれると個人的には嬉しいですね。 bdunderscore.notion.site

実際の使用例?僕はこう使った。

Sender の Custom Tag の用途としては、事前に示し合わせて特定の文字列を指定しておき、その人との間だけで発火できるアニメーションなどを仕込むことが考えられますね。 お砂糖各位、いかがでしょうか?

あとがき

自分で使ってみた感想としては、「Receiver の出力先が Float しか使えない」というのが地味に痛いというか不便だな、という感じです。 ここに Bool や Int を指定できれば Expressions Menu から出す表情やオブジェクトを直接制御しやすいんですが、現状できないのでワンクッション挟む必要があります。

というわけで Canny でその要望が挙がっているので欲しいみなさんは Upvote しませんか?

2022-5-16(Mon) 追記: stable に入っている現在は、 Int/Float/Bool いずれの Expressions Parameter も指定することができます。その代わり(?)、Constant モードで任意の値を設定することができなくなってしまいました。

以上!