PhysBoneがちょっと怖くなくなるnote
もうPBが来てしまいましたね…いよいよ夏が来たようです。
※このnoteは2022/03/07時点で書かれたものです。
現在と内容にズレがあれば申し訳ございません(ある程度は更新する予定ですが…)
※2022/04/20 に更新
2023/05/08 にちょこっと更新
ということで、このnoteでは今回実装されたPhysBoneが少しでも怖くなくなるような感じで解説をしていこうと思います。
はじめに
このNoteはVRChat公式ドキュメントのPhysBone、及びContactなどを元にそれなりに独自解釈しながら作成しております。
一応は更新していくつもりですが、最新の正しい情報は公式ドキュメントから入手してください。それが一番確実です。
…と注意書きをしたところでスタートしてまいりましょう。
概要
今回のAvatarDynamicsで以下の機能が実装される予定です。
なお、以下の機能の実現に必要なのは「VRCSDKのインポート」のみのため、別途で有料の製品を買う必要はありません。
※ただし、VRCSDKに含まれているコレを使って完全に別のゲームの開発に使用しよう…とかはもちろん出来ません、ご注意を。
PhysBone:DynamicBoneに変わって新たに実装される揺れものアセット。
待ち焦がれていた人も多い、「他人の揺れている髪の毛や洋服」などを触ることもこれでできるようになった。
Contact:上記PhysBoneとは別に「専用のコライダー同士でタグを送受信し、一致するタグを受信した場合はパラメータの変更処理を行える」という機能。
これらの機能はなんと、VRChat Questにも実装される。
クエスト版でもいよいよ揺れ物が実装できるようになった。
また、これらの実装に伴い、VRChat内にも新しい設定項目が実装されました。
以下の画像の「Avatar Interactions」が追加項目になります。
とりあえずこんな感じ
今回実装された赤枠のアイコンによって以下のような設定が行なえます。
※左から順番に説明します
◯誰が触れるか(どの範囲まで他人の干渉を許可するか)(Nobody・Friends・Everyone)
・フレンドだけが触れる
・全員が触れる
・誰も触れない
これは他人からPhysBoneで設定された箇所を触られた際にどの範囲の他人なら反応するかを設定します。詳しくは下記画像を参照。
※デフォルトでは「フレンドだけが触れる」設定です
◯Allow / Pause Interactions
自分を含む全ての対象から「触れるかどうか」をオン/オフにする設定項目です。一括でオフにしたい場合などはこちらを使用することをオススメ。
ちなみに「パニックモード」時は強制オフになる。助かる。
◯自分は触れるか(Self Interact)
・触れない
・触れる
PhysBoneで設定された箇所を「自分が触れるか」を設定する項目です。
これをオフにした場合は「DynamicBoneのときにコライダーが未設定だった箇所」のように「自分が触れなくなり」ます。
※デフォルトでは「自分は触れます」
◯触れるかどうかを表示するアイコン ※正式版ではオンオフ廃止
・表示しない
・表示する
※あくまでアイコンで権限を表示するだけのため、実際に触れるかどうかは前述の2つの設定に基づく
補足
前述の設定はすべて他人(ないしアバター)全体に適用されるため、
例えば「このひとは触っていいけど、コイツは触っちゃダメ」とか、
「このひとは触ってもいいけど、他の人は許さない」ということをやりたい場合は別途VRChat内で設定で可能。
VRChatでの挙動
とりあえず
PhysBoneが有効になった状況では、自分のアバターの「頭」「手(手首辺り)」「指(親指を除く)」「胴」「足(概ねかかと付近)」に専用のコライダーが予め付いており、このコライダーで自分や他人のアバターに干渉していく形になります。
※これを標準コライダー(Standard Colliders)と呼びます
これらのコライダーは「パフォーマンスランキングに影響を及ぼさない」「後述するPhysBoneのコライダーとして自動で設定される」特殊なコライダーとして使えます。
今までDynamicBoneの「コライダー設定」に腐心していた方はめっちゃ設定が楽になります。
ただし、
自分や他人のアバターのPhysBoneへ影響を与えられるコライダー設定として自動で適用されるのは「手」と「指」のボーンだけになります。
「頭」「胴」「足」の標準コライダーはこれまた後述する「Contact用のコライダーとして使用」されます(例えば、「胴」の標準コライダーで自分の髪の毛の貫通防止はできないし、「頭」で他人の髪の毛にワシャワシャー!!な干渉はできない)。
その手の貫通防止には素直に[VRC Phys Bone Collider]を使用して設定をしましょう…
ということでUnityいってみよー!
ここからはほぼコンポーネントの説明などに入ります。
独自解釈も多いかもなので要注意です。
VRC Phys Bone コンポーネント
お待ちかねの「無料」「DynamicBoneより軽い」の揺れものがこちらになります。
部分部分でDynamicBoneとは挙動が異なるため、要注意です。
●Root Transform
ここに設定したオブジェクトを含めた子のアイテムが揺れるようになります。
個数制限として1つのPhysBoneコンポーネントにつき、256個までしか揺れない点に注意。
個数は1つのTransform付きのオブジェクト=1つになります。
(要は1オブジェクトにつき1カウント、となります)
もし、それ以上揺らしたい場合は別のPhysBoneコンポーネントにて設定の必要があります。
なお、コンポーネントを分ける=処理が分割されるという関係上、大量のオブジェクトを1つのPhysBoneコンポーネントで動かすよりは、ある程度は分割したほうが良いとのことです。
●Ignore Transforms
ここに設定したオブジェクト(含めた子オブジェクト)は揺れなくなります。
DynamicBoneにおけるExclusionsと同じ機能です。
Rootの子には入っているが、揺れてほしくはない部位はここで指定しましょう。
●Endpoint Position
ボーンやオブジェクトの最終端に追加のボーンやオブジェクトを増やす働きをします。
DynamicBoneにおけるEndLengthと同じような機能です。
「現行のボーン数じゃちょっと揺れの挙動に重みなどが足りなくて…」という際に自然な揺れ方を求める際に使用しましょう。
●Multi Child Type
今のところ(2022/04/21時点)でドキュメントに記載なし。
PhysBoneを入れた場所(もといRootTransform)の子に対しての影響力の違い?
※公式ドキュメントにて追記されたら修正予定
●Integration Type
「Simplified」と「Advanced」のどちらかを選択することができ、
Advancedの場合は「Momentum」が追加されます。
●Pull
ボーンが揺れた際に元の形に戻る力(突っ張る・ふんばる)を発揮します。
1に近いほど結果的に揺れなくなります(カチカチになる)。
逆に0ならば戻る力を失い、揺れからの復帰がなくなります。
※Cボタンを押すことでカーブで部分ごとに設定値の倍率指定が可能です
●Spring ※Integration Typeが「Simplifiedの場合のみ表示」
ボーンが揺れた際に揺れの力の掛かり方を調整します。
1に近いほど揺れた際に勢いが付くようになります(ある程度振り回される)。
逆に0ならば勢いは一切付かず、揺れモノはそのままスッと本来の角度に戻ります。
※Cボタンを押すことでカーブで部分ごとに設定値の倍率指定が可能です
●Momentum ※Integration Typeが「Advancedの場合のみ表示」
上述の「Spring」と同じ効果。
但し以下の「Stiffness」があるため実際には若干異なります。
●Stiffness ※Integration Typeが「Advancedの場合のみ表示」
ボーンが揺れた後、どう戻るかを「Pull」とは別に設定できます。
1に近いほどスイッと元に戻るように(言ってしまえば「忙(せわ)しなく」なる)、逆に0ならばゆっくりと戻るようになります。
髪の毛系は0に近め、胸などは1寄りにすると良いかもしれません。
※Cボタンを押すことでカーブで部分ごとに設定値の倍率指定が可能です
●Immobile Type
以下の「Immobile」がどういう時に効果を発揮するか、を指定します。
「All Motion」…ありとあらゆる動きにおいて効果を発揮します。
例えば下記のImmobileを1に設定した場合、「ジャンプしようが」「VRモードで動き回ろうが」揺れなくなります。多分ほとんどの人はこっちを使わないと思う
「World (Experimental)」…シーンのルートの位置が移動している…(略)、要するに、ワールド内を移動している時にのみ効果を発揮します。
例えば下記のImmobileを1に設定した場合、「ジャンプや移動」は揺れませんが、「VRモードでリアルに動き回る・立ったりしゃがんだりする」とImmobileの設定を無視して揺れます。
※ただし、将来的に仕様が変わる可能性がある、とのことです
●Immobile
アバターが動いた結果によってどれくらい当該ボーンに影響を及ぼされるかを決定します。
1に近いほどPull同様に結果的に揺れなくなります(カチカチになる)。
但しPullと異なり、こちらの場合は物(コライダー)にぶつかってズレたり、引っ張ったりは有効です(なので掴んで位置をズラした場合はPullやSpringの値によって元の位置への戻り方が決まる)。
※Cボタンを押すことでカーブで部分ごとに設定値の倍率指定が可能です
●Gravity
重力です。1ならば地面、-1ならば空(上空)に向かって重力が掛かります。
0.01辺りの値を入れるとある程度下向きになるのでなんというか…生きている感が出ます。
※Cボタンを押すことでカーブで部分ごとに設定値の倍率指定が可能です
●Grabity Falloff ※Gravityが0以外の値でないと操作不能
重力の掛かり方を設定していてなおかつ「でもある程度は元ボーンの形状に沿ってもらいたいなあ」という贅沢な悩みを解消してくれる設定。
1に近いほど元ボーンの形状に沿うようになります。
逆に0の場合は常に「Gravity」の重力が掛かった挙動になります。
※「Gravity」の値と相談して決めましょう
●Allow Collision
現行では「下記Collidersで指定された以外のコライダー(=他のユーザーの手など)でこのコンポーネントで設定された揺れモノに触れるようにするか?」という設定になります。
「自分以外には絶対に触られたくない」という場合はチェックを外しておきましょう。
※アップデートによって「True」「False」「Other」の3択になりました。
ですが、触られたくない場合は「False」・触られてもいい場合は「True」で設定する感じになると思われます(Otherの意味がないような)。
●Radius
この値を0より大きく設定することでコライダーとぶつかりやすくなり(貫通をある程度防止できるようになり)、また掴み判定が発生するようになります。
DynamicBoneの同名の設定パラメータと同じ機能です。
あえて掴みたくない(掴まれたくない)場合は0でOKです。
※Cボタンを押すことでカーブで部分ごとに設定値の倍率指定が可能です
●Colliders
ここに指定されたコライダーは同じコンポーネント内のオブジェクトに位置ズラしなどの影響を及ぼすようになります。
DynamicBoneでのコライダー設定と同じになります。
前述した「標準コライダー」はデフォルトでここに設定されている扱いのため、髪の毛を触ったりするのに自分で設定する必要はありません。
●Max Angle
ボーンやオブジェクトを揺らしたり掴んだりした際に「どの角度まで曲げていいか」を設定する項目です。
角度を明示して設定できるようになったため、おかしな角度まで傾く事を防止しやすくなりました。
※Cボタンを押すことでカーブで部分ごとに設定値の倍率指定が可能です
●Freeze Axis
ボーンやオブジェクトを揺らしたりする際に「特定の方向にのみ」揺れるように設定したい!という時にチェックを入れます。
下記「Freeze Axis Angle」とワンセットで使用されるパラメータです。
●Freeze Axis Angle
「Freeze Axis」のチェックが入っていた場合に、「どの方向にのみ揺れるようにするか」の角度を決定するパラメータです。
前髪部分などのちょっと揺れる方向に拘りたい部分に使用するパラメータになります。
●Allow Grabbing
ここにチェックを入れると、コンポーネントで設定された揺れものは掴むことが出来るようになります。
「Allow Collision」にチェックが付いている場合は他人にも掴まれるようになるので気をつけましょう。
●Allow Posing ※Allow Grabbingとセット?
揺れものを掴んでトリガーを押下した際に「その位置で固定されるか」を設定します。
ロングヘアー系だと髪を結うロールプレイとかが出来るかもしれません。
こちらも「Allow Collision」にチェックが付いている場合は他人に掴まれて遊ばれる可能性があるので気をつけましょう。
●Allow〇〇系列の拡張 ※2023/05/08に追記
Allow Collision・Allow Grabbing・Allow Posingが「True」「False」「Other」の3択に変更され、Otherの場合はこの設定を誰を対象に有効にするかを決められるようになりました。
●Grab Movement ※Allow Grabbingとセット
揺れものを掴んで動かす際に「どのような感じで引っ張られるか」を設定します。
1に近い場合は「掴んだ挙動に素直に動き」、0に近い場合は前述の「PullとSpringの設定値」に基づいて動きます。
ある程度の華やかさを担保するのであれば0よりをオススメ。
●Max Stretch ※Allow Grabbingとセット
揺れものを掴んで動かす際に、「どれだけ伸びるか」を設定します。
ゴムっぽく伸びるのでそれがOKな部位に使用しましょう。
※Cボタンを押すことでカーブで部分ごとに設定値の倍率指定が可能です
●Snap To Hand
前述のAllow Grabbingにて掴めた際に、ボーンがより掴んだ場所に沿うようになるみたいです(掴んだという実感が湧きやすくなるかも)。
●Is Animated
ボーンなどを操作するアニメーションが実行される際に定位置に戻るかどうかを設定します。
ケモ耳などで喜怒哀楽の表情を取る場合はチェックを付けておくことをオススメします。
●Reset when Disabled
設定されているPhysBoneのコンポーネントのチェックが外れた(動作を停止させた)際に、ボーンの角度や位置が揺れたりする前の状態に戻すかの設定を行います。
揺れ物のリセット機構を作る際に使用してみると良いかもしれません。
●Parameter
ここに入れたPrefix(接頭辞)に応じて以下のパラメータが自動で生成されるようになり、このパラメータを用いたアニメーター(アバターギミック)を作成することができるようになります。
※アニメーター側で宣言しておかなきゃダメだよ!(EXパラメータに別で宣言しておく必要はない)
<入れた文字列>_IsGrabbed:Bool型で、掴まれたかどうかを判定するパラメータとなる。
<入れた文字列>_Angle:Float型で、0~180°までどこまで曲げられているかを0~1までの値で表現するパラメータ。
<入れた文字列>_Stretch:Float型で、「Max Stretch」の値も含めてどこまで伸びているかを0~1までの値で表現するパラメータ。
●Gizmo
Unity内でPhysBoneのボーン情報などの表示をする設定項目。
大量に表示させるとUnityが重くなるので改変作業時は程々に。
VRC Phys Bone Collider コンポーネント
標準コライダー以外で使用したいコライダーはこちらで設定します。
特に、アバターの足の付け根・及びふともも部分には標準コライダーは設定されないため、スカート系アバターの場合は実装必須です。
※PhysBone側のCollidersでの設定も必要
●Root Transform
指定したオブジェクトにコライダーを配置します。
DynamicBoneと異なり、コンポーネントを取り付けた場所以外の自由な所に配置ができるようになりました。
●Shape Type
コライダーの形状を設定します。
Sphere(球状)とCapsule(カプセル状)とPlane(板)の3種類から指定できます。
●Inside Bounds
コライダーにぶつかることで位置を移動させる通常のコライダーとは正反対に「コライダーの中から出ないようにする」という設定が行なえます。
DynamicBoneにもあったインサイドコライダーと同じです。
●Radius ※Shape Type:Planeのみ非表示
コライダーの大きさを設定します。
PhysBone側のRadiusと合わせ、いい感じの大きさに設定しましょう。
●Height ※Shape Type:Capsuleのみ表示
コライダーの縦の長さを設定します。
こちらもいい感じの長さにしましょう。
●Position
DynamicBoneコライダーのCenterと同じ設定値になります。
オブジェクトの位置を直接ズラせない場合はこちらでズラせます。
●Rotation
コライダーの回転を設定できます。
CapsuleとPlaneで向きを合わせる時に使用します。
※Sphereでも出現はしますが…意味はないかなと。
●Bones As Sphere
チェックを入れた場合、PhysBoneコライダーの衝突判定がDynamicBoneのように判定が「Capsule(カプセル)」から「Sphere(球形)」に変更されます。
結果として「コライダーの隙間に入り込んでしまう」事は起きやすくなるものの、Dynamic Boneと判定が異なるので自動変換で破綻してしまうという問題が回避しやすくなりました。
VRC Contact Sender コンポーネント
今回のAvatarDynamicsにおいて重大な新機能のContact部分を司るものであります。
後述のVRC Contact Recieverと組み合わせて使います。
ここでコリジョンタグを設定することで任意のオブジェクトに専用のコリジョンを設けることができ、Recieverと組み合わせてパラメータを変動させ結果としてアニメーションを実行する…ということが出来ます。
通常コライダーでは足りない!という場合に使用します。
●Root Transform
専用の送信用コライダーの位置を決める設定値です。
任意で決めることも出来ますが…大体は小物の切っ先など付いていてほしい場所に付けるかなと。
●Shape Type
送信用コライダーの形状を決定します。
SphereとCapsuleのどちらかしか使えません。
●Radius
送信用コライダーの大きさを決定します。
小ネタですが、小物の大きさに厳密に合わせるより若干大きめの方が判定にぶつかりやすくなってオススメです。
●Height ※Shape Type:Capsuleのみ表示
コライダーの縦の長さを設定します。
●Position
コライダーの位置を決定します。
未設定だと原点の位置にコライダーが来てしまうので、別の位置に置きたい際はきちんと設定しましょう。
●Rotation
コライダーの回転を決定します。
Capsuleの場合はこれで角度を合わせましょう。
●Collision Tags
結構特殊です。
Addボタンで増やして付けたタグ名がこのコライダーでReceiverに触った際に「私は<〇〇>というタグです!」とReceiver側に伝えられるデータになります。
※ちなみに大文字小文字は区別されるらしいです、要注意。
VRC Contact Receiver コンポーネント
上記の「VRC Contact Sender」とここで設定されたコライダー同士がぶつかり合うことでコリジョンタグを受信し、最終的にパラメータとして反映させるためのコンポーネントになります。
●Root Transform
専用の受信用コライダーの位置を決める設定値です。
●Shape Type
送信用コライダーの形状を決定します。
こちらもSphereとCapsuleのどちらかしか使えません。
●Radius
送信用コライダーの大きさを決定します。
●Height ※Shape Type:Capsuleのみ表示
コライダーの縦の長さを設定します。
●Position
コライダーの位置を決定します。
未設定だと原点の位置にコライダーが来てしまうので、別の位置に置きたい際はきちんと設定しましょう。
●Rotation
コライダーの回転を決定します。
やはりCapsuleの場合はこれで角度を合わせましょう。
●Collision Tags
「このReceiverはここで指定されたコリジョンタグだけを受信するよ!」という設定になります。
当然(?)、指定されたもの以外は受信しないので注意。
●Allow Self
このコリジョン判定を「自分で発生させられるよう」に許可する設定です。
オフにすると「自分のSenderやコライダーでは反応しなくなります」。
●Allow Others
このコリジョン判定を「他人が発生させられるよう」に許可する設定です。
オフにすると「他人のSenderやコライダーでは反応しなくなります」。
●Local Only
このコリジョン判定を「ローカルのみ」(だから、本人だけ?)で反映させるようにします。
結果として、触られた結果発生するアニメーションは他人には見えないようになります。
●Receiver Type ※Receiver Type系はかなり曖昧です、誰か指摘か報告求む
以下のConstant・OnEnter・Proximityから、「どの処理としてSenderの値を受け取るか」を選択します。
●Constant
Senderのコライダーと接触している間は1になります。
接触しなくなると0になるようです。
●OnEnter
Senderのコライダーと接触している間は常に1として出力されます。
接触しなくなると0になるようです。
※Constantとの違いは後述…
●Proximity
コライダーの中心点を1として、距離に応じて0~1までを出力します。
なお、複数の受信を受け付けているコリジョンタグがいた場合は一番近い値を出力します。
●Parameter
「Receiver Type」毎の条件を満たした場合、ここで名前を入れておいたパラメータが影響を受けることになります。
アニメーターコントローラーのパラメータ名をコピペで入れておくことをオススメします。
●Value ※Receiver Type:Proximityのみ非表示
Constant・OnEnterの条件を満たした場合に「Parameter」にどのような値が入るのかをここで設定します。
なお、Proximityだった場合は0~1までのFloat型の値が自動で入ります。
●Min Velocity ※Receiver Type:OnEnterのみ表示
コライダーに接触した際に「どれくらいの速度ならOKとするか」を設定する設定値になります。
※Constantとの違いは接触時に最低速度が要求される点
補足
対応しているSDK
PhysBoneはAvatars3.0(アバター3.0)で使用可能になるコンポーネントです。
SDK2には非対応となるので気をつけましょう。
※SDK3ワールド向けの実装も要望としてある模様
VRChat公式でオススメの設定値
下記動画のいち部分を切り取ったものがこちら。
Hair(髪の毛)/Tail(しっぽ)/Chest(胸)/Skirt(スカート)/Chain(くさり)(アクセサリ系)の一通りを抑えているので、これを参考に調整すると良いかもしれません。
但し、タイプが「Simplified」の場合のため、「Advanced」だとちょっと変わってくる点に注意。
PhysBoneで生成されるパラメータについて
「VRC Phys Bone」および「VRC Contact Receiver」コンポーネントでは、「Parameter」の設定値に基づいてパラメータが生成できますが、このパラメータは「Expressions Parameters」に定義しなくとも各ユーザー間でパラメータ値が同期されます。
但し、EXパラメータのようにワールドにいればどこでも同期する、わけではなく視界内に居ないと同期しないとのことなので要注意。
Unity上での自動変換時の問題
現行の仕様として、VRCSDKの機能でDynamicBoneからPhysBone用への変換処理を行う場合は「DynamicBoneをインポートしていない(未購入など)」環境では「変換処理そのものが行なえません」。
但し、有志のツールを使えばDynamicBoneなしでも変換できるツールが出ています。
DynamicBoneなしでも変換できるツールです。
こちらを使うのが安牌っぽそうです。
そもそもデフォルトで触れる設定ってどうなってんの?
●VRC Phys Bone
・Allow Collisionはオン
・Allow Grabbingもオン
・Allow Posingもオン
・但しRadiusは0(DynamicBoneから変換した場合はDynamicBone側の設定に準ずる)
そのため、Radiusの設定次第で他人から触られる可能性あり。
注意点を挙げたツイート
HipsボーンをPhysBoneのルートには設定しないで!
他人が触れないようにする方法
締めのあいさつ
PhysBone、アバター同士に色々な交流の仕方が実現できるようでまた1つ新しい世界が見えてきそうです。
※アバター製作者様…お疲れさまです…m(_ _)m
もしこのnoteがキッカケである程度はPBについて分かった、などのご意見があれば幸いです。