2025-05-02 Parent Constraint の「Activate」ボタンについて
This page is available in English: English
このページは AI(Claude)によって翻訳されています。翻訳に誤りが含まれる可能性があります。
Skinned Mesh Constraint を開発している最中に、奇妙なことに気づいたので、 どこかに記録しておきたいと思いました。
Skinned Mesh Constraint は、メッシュのスキニングによって頂点が動くのと同じように、Parent Constraint を動かすためのツールです。
アプローチ #1:ボーンを対象にした Constraint を Activate する
私はこれまで、Parent Constraint の Activate ボタンを押すと、GameObject が、レストポーズからの相対的なウェイトの割合に応じて、 ソースの Transform に追従するようになるものだと思っていました。
このため、Skinned Mesh Constraint コンポーネントを作ろうとしたとき、最初のアプローチは、メッシュにペイントされたウェイトを収集し、 対応する Parent Constraint のソースを設定してから、リフレクションを使って(VRC 以外のプロジェクトで)Activate ボタンを押すというものでした。
ところが、ボーンを動かすと、Parent Constraint の動きがメッシュのスキニングと同じになりません(行き過ぎてしまいます)。
アプローチ #2:ボーン内に置いた新しいオフセット用 Transform を対象にした Constraint を Activate する
次に、レスト時に Position Constraint と同じ位置になるようオフセットした新しい Transform を、ボーンの内側に作ってみました。
この方法はうまくいきました。つまり、Parent Constraint が内部でどう動作するのかについて、私は何か勘違いしていたのです。これらの観察結果をもとに、 2 つの Discord サーバーで助けを求めました。
すると Sacred さんという方から、私のアプローチ #2 がメッシュのスキニングに対する正しいアプローチだと教えてもらいました(Sacred さんはこのアプローチを Voxian さんという別の方の功績としていたので、 私は再発見しただけです)。また、複数の Constraint(ボーン 1 つにつき Parent Constraint 1 つ)を使う、それより劣る別の方法もあるとのことでした。
この方法には Constraint の数が少なくて済むという利点がありますが、Transform の参照がより多く必要になります。
この Discord でのやり取りをきっかけに、3 つ目のアプローチの調査を始めました。
アプローチ #3:オフセットの Transform を手動で計算する
Activate ボタンをクリックすると、Parent Constraint は、レスト時の Constraint ソースに対する相対オフセットの情報を保存します。
アプローチ #1 では、これらのオフセットに何らかの値が入っています。
アプローチ #2 では、これらのオフセットはすべてゼロです。
この新しいアプローチでは、先ほど作った、ボーン内のオフセット用 Transform の位置と回転を、これらのオフセットにコピーしてみました。 Constraint は、それらのオフセット用 Transform ではなく、ボーンを直接対象にしています。
結果として、これらのオフセットを手で書き込むことで問題が解決しました。追加の Transform を参照する必要もないため、 これが Skinned Mesh Constraint で採用している方法です。
オフセットは、回転については (Quaternion.inverse(sourceTransform.rotation) * constraint.rotation).eulerAngles を使って計算し、
平行移動のオフセットについては こちらの回答を参考にしています。sourceTransform.InverseTransformPoint(constraint.position)
では、Constraint の Activate ボタンは何をしているのか?
Constraint の Activate ボタンがどう動作するのか、私にはわかりません。
このボタンが何をしているのかを可視化してみましたが、奇妙です。Activate をクリックすると、脚のボーンのオフセットが、予想外の位置を指しています。

上の画像では、赤い線の先端がオフセットのワールド空間での位置を指していますが、Constraint の対象となっているオブジェクトはレスト状態です。
メッシュのスキニングに従うように Parent Constraint を設定した場合、レスト位置そのものがオフセットなので、赤い線はまったく表示されないはずです。
これ以上のことは私にもわかりませんが、 これは、Constraint の Activate ボタンを押した場合の挙動が、
オフセットを手で計算した場合とは異なることを意味します。
2025-05-03 更新: Activate ボタンの仕組みについて新しい情報を知ることができたので、 この記事は、製品のアップデートとともに、後ほど更新する予定です。