Physboneで紐を引っ張ると何か起きるギミックを作った解説(Physbone Stretch)
はじめに
ととやまです。
アニメーションレイヤーとの格闘の末、ようやく『壊れた蛍光灯ヘイロー』のバージョン2をリリースすることができました。もはやシンプルではなくなりました…。
前々からやってみたかった「ModularAvatarの対応」「ガラス片の回転」、そして「蛍光灯の紐を引っ張るとEmissionが切り替わる」ギミックを導入しました。(最後のギミックは「難しいから”いずれ”にしよう…」と思ってたのですが、Resonite版でギミック制作をしてくれた方がガッツリ常夜灯まで加えてくださったので、さすがにVRChat版にも無いとということでなんとか実装しました…。大変だった…。)
これを調べてみると、なかなかにジャスピンな情報が出てこない。「紐を引っ張ったら切り替わるギミック」って意外にも情報が少ない...?
ということで、自分の振り返りのためにも実際に組んだギミックを解説したいと思います。あくまでも「一つの解」なので、もっと最適化されているものもあると思います。なんならまだ初心者同然なので、まだまだ理解しきれていないところも多いと思います。
ちなみに、Physboneのギミックをテストするときは、VCCから「Gesture Manager」をプロジェクトにインストールする必要があります。(教えてもらうまで数値を直接入力してテストしていました…。)
Physboneのアニメーションパラメーターについて
Physboneにはギミック制作に使える以下のアニメーションパラメーターが存在しています。
・Parameter_IsGrabbed:掴んでいるか(Boolなのでtrue or false…つまり”してる”か”してないか”で判定)
・Parameter_IsPosed:固定しているか(Boolなのでtrue or false)
・Parameter_Angle:曲がり具合(設定最大値に対して0~1)
・Parameter_Stretch:伸び具合(設定最大値に対して0~1)
・Parameter_Squish:潰れ具合(設定最大値に対して0~1)
今回はこれらのうち「Physbone Stretch」を使って、紐の伸び具合でギミックが動作するものを作っていきます。
下準備
①紐にPhysboneを設定する
●掴めるようにする
・Collision:衝突判定が無いと掴めません。小さすぎると掴みにくいので、気持ち大きめのほうが良いかも
・Grab&Pose:Arrow GrabbingをTrueにして掴めるように
●伸びるようにする
・Stretch & Squish:MAX Stretchを設定(元の長さに対して何倍の長さ分が伸びるか。私は0.5にしています。小数も受け付けるようです。)
●アニメーションレイヤーで使うパラメーター名を設定する
・Options:Parameterを任意のものに。ここでは「Rope」にしているので、「Rope_Stretch」が伸びの値を参照するアニメーションパラメーターになります。
②アバター用にExperssion Parameterファイルを作成
先程作った「Rope_Stretch」のパラメーターをアバターが使えるように、ModularAvatarで移植する用のパラメーターファイルを作ります。
「右クリック→Create→VRChat→Avatar→Experssion Parameter」で作成します。Physbone Stretchの仕様通り数値を読み取るので、TypeはFloatを指定します。
③モデルへのModularAvararの設定
蛍光灯モデルにModularAvararを設定します。今回使用したのはこの3つです。
●MA Bone Proxy:どこのボーンにモデルを紐付けするか。いちいちArmatureを開いて配置する必要がなくなります。今回は頭に付けるので、Bone referenceをHeadに設定。
●MA Merge Animator:蛍光灯モデルのFXレイヤー(=アニメーションレイヤー)をアバターのFXレイヤーに移植します。蛍光灯モデルアニメーションレイヤーは後述の工程で作っていきますので、一旦はブランクで大丈夫です。アバターに入れてテストする際に入れましょう。
●MA Parameter:アニメーションパラメーターの値を移植します。今回は「Rope_Stretch」のみ。先程作ったExperssion Parameterを「アセットからインポートする」にD&Dすると反映されます。
では、アニメーションレイヤーを作っていきましょう。適当なアニメーションをモデルにD&Dすれば、自動的にモデルへのAnimatorの設定とアニメーションレイヤーの作成を行ってくれます。(Expression Parameterのように右クリックからも作成可能です。)
紐を引っ張ったら音が鳴るギミック
まず蛍光灯ヘイローの「紐を引っ張ったら音が鳴る」の部分です。これは「Sound_SourceコンポーネントのついたオブジェクトのON/OFFを切り替える」ことで実装しています。
Sound_Sourceコンポーネントが付いたオブジェクトを作成しておきます。コンポーネントの「Play on Awake」にチェックをつけると、オブジェクトがONになったときに音がなります。これを切り替えることで音を鳴らしています。
さて、アニメーションレイヤー部です。Animationには「Sound_SourceオブジェクトのON」「Sound_SourceオブジェクトのOFF」、Transitionには今回の基幹部分である「Physbone Stretch」を使っています。
「Physbone Stretch」は「Physboneの最大伸びに対して、どれくらい以上、どれくらい以下」という判定を使うことができます。
では実際にアニメーションレイヤーがどのように動いているのか説明していきます。
最初は「Sound_SourceオブジェクトのOFF」ステートに入ります。
ここで紐を引っ張ると「紐が最大伸びの0.5部分以上になったら」のTransitionが起動し、次の「Sound_SourceオブジェクトのON」ステートに入ります。
そして、紐を緩めると「紐が最大伸びの0.2部分以下になったら」のTransitionが起動し、最初の「Sound_SourceオブジェクトのOFF」ステートに入ります。
このようにして、効果音ギミックを実装しています。
紐を引っ張ったら3段階でEmissionが変わるギミック
では、蛍光灯の3段階変化はどのようになっているのでしょうか。ここでは蛍光灯の色に合わせて「白蛍光(Emission_ON)」「橙蛍光(Emission_Middle)」「蛍光なし(Emission_OFF)」のアニメーションステートで説明します。
(アニメーションに関しては、Quest対応シェーダー(Standard Lite)との互換性のため、Emission_Colorキーで発光を制御しています。これらのシェーダー制御系のキーも、Add Property→Skinned Mesh Rendererのところから追加します。他のシェーダー基準で作るなら、直接EmissionをON/OFFできるキーで制御するのが明確かもしれません。)
まず始めに「白蛍光」のステートに入ります。これで蛍光灯が白色に光っている状態になります。
続いて、「伸びが0.2以下のときは次のステートに行く」のTransitionで、「idle 1」に行きます。このステートは待機のために作成しており、アニメーションは何も設定していないので、蛍光灯は白色に光ったままです。
そして「伸びが0.5以上のときは次のステートに行く」のTransitionで、「橙蛍光」に行きます。
そして、「伸びが0.2以下のときは次のステートに行く」のTransitionで、「idle 2」に行きます。先程同様に、このステートで一旦伸びの判定をリセットして、次の伸びのために待機します。
このようにして、「伸びたら次の色のステート」「縮んだら待機ステート」というようにしてTransitionを組んでいきます。このような輪っかを作ることで、3段階変化ギミックを実装しています。
テストはGesture Managerを適用した状態のPlayモードで行います。実際に動いたら成功です。
おわりに
これでざっくりとした一通りの解説は終了です。まだまだ知らないこともたくさんあるので、よりブラッシュアップした表現や手法を使えるようになりたいですね…。ぜひみなさんも色々作ってみてください、BlenderもUnityもいつでも始められてしかも無料!
ためになったらモデルを購入してくれると、なんとエナドリ2本買えるくらいの投げ銭になります。1000円でラーメン食べれます。嘘です、ワールドやモデル制作などの費用に充てます…。
ととやま