はじめに
VRChatのワールドでカーテンを手でつかんで開けたり閉めたりしたいという話です。
以下のワールドでやってることを実装します。
具体的には下のTweetみたいな挙動をします。テスト段階なので実際のワールドとはちょっと違います。
これを応用するとカーテンも手で開けられるhttps://t.co/kmVHquBlPJ pic.twitter.com/41It0kBn2h
— 雨降り(あめふり) (@It__was__rainy) 2023年3月26日
結論
スライドドアギミックの取っ手の動く範囲を基準に、取っ手の現在座標から終点までの距離を0~1に正規化して、100倍してカーテンメッシュのシェイプキーに突っ込む。
やり方
2行で終わるのはあんまりなのでもうちょっとだけ詳しく書きます。
用意するもの
最低限必要なもの
・スライドドアギミック
・開閉シェイプキーのあるカーテンのモデル
お好みで用意するもの
・カーテンシェーダー
これ入れてカーテンがゆらゆらしてるだけでだいぶいい感じです。おすすめ。
下準備
カーテンのモデルを用意します。お好みでカーテンシェーダーも適用しておきます。
説明のために片側だけにしています。
※このモデルは以下の無料アセットに開いた状態のシェイプキーを追加したものになります。影が汚いのはトポロジーを下手にいじったせいです。
スライドドアギミックのPrefabを置きます。カーテンの端(掴む方)に取っ手が合うようにします。
取っ手の終点を用意します。高さと奥行きは取っ手と同じ座標にして、横だけカーテンが開ききったときの端に合わせます。カーテンのメッシュが横向いてるので画像だとグローバルZ軸が左右になってますが気にしないでください。
スライドドアギミックのUdonのパラメータを調整します。
これはZ軸方向にスライドする向きに配置した上にドアの裏表もひっくり返ったままなのでこんな奇妙なパラメータになっていますが、ちゃんとX軸が左右になるように配置していればほとんどいじる必要はないです。Maxの値だけ適当にいじっておけばいいです。
詳しいことはスライドドアギミックのマニュアルを参照してください。
下準備が終わりました。
Udonを用意する
カーテンの開閉のためのUdon本体を用意します。
Udonの中身の説明をするのが面倒なので、Prefabを用意しました。この記事の後ろの方にDLリンクを貼っているので必要な方はそちらからどうぞ。
こいつのInspectorを、下のように設定してください。
・GrabPoint → スライドドアギミックのハンドルのメッシュ部分
・EndPoint → 取っ手の終点(ここではHierarchyにあるEndPointという名前の空オブジェクト)
・CurtainMesh → 開閉シェイプキーのついたカーテンのメッシュ
設定が終わったらClientSimで動作確認します(画像でスライドドアギミックのPrefabが一つ増えていますがパラメータ確認用に置いただけなので関係ないです)。
動けばOK。あとはスライドドアギミックのメッシュを非表示にして取っ手のコライダーの調整をします。StaticModelはオブジェクトごと非表示にしても問題ありません。
MoveModelのコライダーを残しておけば、カーテンが閉まっている間は向こう側に行けないという状態になります。
既知の問題(?)点
シェイプキーが100にならない
この設定だときっかり100になりません。たぶんUdonの計算がよくないせいだと思いますが、よくわからないのでそのままです。直し方わかる人は教えてください。
動かしすぎるとシェイプキーの値が小さくなる
スライドドアギミック側のパラメータ次第ではEndPointを若干超えて取っ手を動かすことができますが、取っ手がEndPointを超えるとシェイプキーの値がだんだん小さくなります。計算がよくないのでわかる人は以下略
ライトベイクに不向き
シェイプキーを使う都合上SkinnedMeshになるので、ライトベイクに向きません。BakeryならShadowMsakをごにょごにょすればベイクした上からリアルタイムの影を落とせます。やり方はlilさんがTweetしてくれています。
シェーダー改変なしで普通に解決できた
— lil (@lil_xyzw) 2023年3月17日
1. Render Mode を Shadowmask に
2. Occlusion probes をオンに
3. Directional Light に Bakery Directional Light を Add Component して Bake contribution を Shadowmask and Indirect に
4. Light Probe を適切に配置
5. Render & Render Light Probes
Udonの中身を知りたい人向け
中はこうなっています。
やっていることは冒頭で言ったとおりですが、付け加えるならシェイプキーに突っ込む値を100から引く処理をしています。
これはシェイプキーを閉→開でつくってしまったからなので、開→閉にしておけばここの処理はいらないと思います。
Prefabの配布
解説に使ったPrefabが入っているだけのUnityPackageです。全VRChatワールドのカーテンがカシャカシャできるようになることを願っています。
おわりに
カーテンの実装にあたってお借りしたすべての素材とその作者ならびにUdonのアドバイスとテストに協力してくれたフレンドに感謝します。
あとは動かすときにSEとかついたら楽しそうですね。スライド速度を音源の再生速度とかピッチにいい感じに突っ込んで、こう……
そういえば最近PhysBoneに押込み機能がついたので、もしワールドにPBが実装されたらそちらのほうが簡単なような気がします。早く実装してくれ。