🛠️

DynamicBoneの揺れを制限する

2023/12/16に公開

この記事はResonite Advent Calendar 2023の16日目の記事です。
https://adventar.org/calendars/8649

今回の内容

DynamicBoneの揺れを自力で制限をする方法を書いていきます
もしかしたら標準の機能でできるかもしれません

設定方法

まずSlotの準備をして、そのあとFluxを設定します

Slotの準備

揺れ物のボーンSlotを複製して配置をしていきます
ボーンSlotのコピーを2個作ります
分かりやすいように名前を変えてあります。必須ではないです
mesh.〇〇:オリジナルのボーンでMeshに紐づいているもの
DB.〇〇:DynamicBoneの設定をするもの
base.〇〇:ボーンの初期位置を覚えておくためのもの

もしDynamicBoneが既に設定してある場合は
DynamicBoneのEnabledのチェックを外してからボーンをコピーして
mesh.〇〇とbase.〇〇のDynamicBoneを削除すればよいです

さらに配置を変えます
DB.〇〇とbase.〇〇が同じ親を持つようにbase.〇〇を移動します

Fluxの設定

Fluxを以下のように設定します

1:基準の姿勢からどのくらい回転しているかをfloatQで取得し軸と角度に分けます
2:角度が0~360で出力されるので-180~180に変換します
3:角度を-60~60に収まるように制限します

このfluxをボーンの数だけ設定して完成です
https://youtu.be/7opJHy7YfRw

仕組み解説

簡単に仕組みを解説します
ボーンの揺れはSlotのRotationの変化で表されます
そしてRotationにはfloatQが使われていて
floatQには軸と回転角に分解するToAxisAngleノードがあります
この分解後の回転角に制限をかけてAxisAngleでまたRotationに戻してあげれば
揺れを制限することができます

角度を制限するときにClampやMin/Maxを使っても良いですが
角度が上限を超えたときに揺れがカチッと止まって硬い感じがします
なので緩やかに上限に達するようにSigmoid関数を使います
Sigmoid関数は次のような関数で、緩やかに上限/下限に近づくような形をしています

赤がSigmoid、緑がClamp
Sigmoid関数の出力が0~1なのでRemapで-1~1にしています

問題点

あくまでも疑似的なものなので問題もあります
上の動画を見ると分かりますがボーンの物理演算と制限の計算が別々なのでMeshとCollisionにずれが出ます
ボーンの数が増えたり、長いボーンがあるとずれが大きくなってしまいます
あと処理が重くなります

完成

これをアバターに適用すれば破綻が少なくいい感じの揺れ物の完成です

Discussion