2026/05/22
ピボットをコントローラで制御する
こんにちは。
BACKBONEの村上です。
今回は、コントローラのTranslateを使用してPivotを制御する方法(コントローラ)についてご紹介します。

上記の動画では、コントローラの移動(Translate)を利用して、回転の起点となる「Rotate Pivot」の位置を制御しています。具体的には、コントローラの Translate 値を Rotate Pivot に接続することで(※詳細は後述)、このような挙動を実現しています。
Rotate Pivot は別コントローラで制御する構成も可能ですが、今回は「1つのコントローラで Pivot もあわせて操作する方法」をご紹介します。また、本構成では、黄色のコントローラの移動を Pivot 制御用途として扱っているため、子階層にある水色のコントローラへ直接的な移動影響を与えにくい、というメリットがあります。
本記事では、以下の内容について順にご紹介していきます。
1.Pivotについて
2.Pivot制御をひとつにまとめたコントローラの作成方法
1.Pivotについて
まずは、Pivot の基本的な仕組みと動きを、ざっくりと確認していきます。
Pivot には、「Local Space(ローカル空間)」と「World Space(ワールド空間)」の考え方があります。
主に確認する要素は以下の通りです。
Local Space に関するもの
- Local Rotate Pivot
- Local Scale Pivot
World Space に関するもの
- World Rotate Pivot
- World Scale Pivot
また、Pivot 制御に関連する主な Attribute は以下の4つです。
- Rotate Pivot
- Rotate Pivot Translate
- Scale Pivot
- Scale Pivot Translate
今回はこの中から、「Rotate Pivot」と「Rotate Pivot Translate」を使用していきます。
(今回は Cube を使って確認します)
なお、これらのアトリビュートはデフォルトでは Channel Box に表示されていません。
そのため、Channel Control から「Rotate Pivot」と「Rotate Pivot Translate」を追加し、Channel Box に表示させています。

Pivot の動きを視覚的に確認しやすくするため、今回は Locator を作成しています。
比較用として、以下の 2 パターンを用意しました。
1.「Rotate Pivot」を Locator の Translate に接続したパターン
2.「Rotate Pivot Translate」を Locator の Translate に接続したパターン
それぞれのアトリビュートへ値を入力し、どのような挙動になるのかを確認していきましょう。
1.Rotate Pivot

上記の動画では、「Rotate Pivot」を Locator の Translate に接続しています。
この状態で「Rotate Pivot」の値を変更すると、Move Tool と Rotate Tool のマニピュレータ位置が、指定した Rotate Pivot の位置へ移動します。一方で、Scale Pivot は変更していないため、Scale Tool のマニピュレータ位置には変化がありません。

上記の動画では、「Rotate Pivot」の値を変更した後に回転を行い、その後さらに「Rotate Pivot」を変更した際の挙動を確認しています。
これは、回転処理が内部でおおよそ次のような順序で計算されているためです。
① 回転計算に使用する座標空間を、Pivot の位置へオフセットする
② その座標空間を基準として、「Rotate Axis」と「Rotate」の回転計算を行う
③ 回転計算後、座標空間を元の位置へ戻す
つまり、「Rotate Pivot」は、オブジェクト自体を直接移動しているわけではなく、「回転計算を行う基準位置」を一時的に移動するためのオフセットとして機能しています。そのため、動画のように Pivot を移動すると、一見オブジェクト位置が変化しているように見えますが、実際には回転基準となる座標空間が移動しているだけです。
Attribute Editor を確認すると、「Local Rotate Pivot」や「World Rotate Pivot」に、現在の Pivot 位置が反映されていることが確認できます。

2.Rotate Pivot Translate

上記の動画では、「Rotate Pivot Translate」を Locator の Translate に接続しています。
この状態で「Rotate Pivot Translate」の値を変更すると、Cube が移動しているように見えます。
ただし、実際には Translate の値自体は変化していません。
これは、「Rotate Pivot」の位置変更によって発生する見た目上の位置変化を補正するために、「Rotate Pivot Translate」が内部的にオフセットとして機能しているためです。また、各マニピュレータ位置も、「Rotate Pivot Translate」の値に応じた位置へ変化していることが確認できます。
Attribute Editor を確認すると、「World Rotate Pivot」や「World Scale Pivot」の値が、「Rotate Pivot Translate」の変更に応じて変化していることが確認できます。

2.Pivot制御をひとまとめにしたコントローラの作成方法
シンプルな構成のデータを使用しながら、順を追って説明していきます。
まず、下図のように、カーブで作成した黄色のコントローラ「ctrlA」を用意し、その子階層に水色のコントローラ「ctrlB」を配置します。今回は、この黄色のコントローラに対して、Pivot 位置も含めて 1 つのコントローラで制御できるよう設定していきます。

① まずは試しに、「ctrlA」の Translate を「Rotate Pivot」へ接続し、挙動を確認します。
この状態で Translate を移動すると、「Rotate Pivot」にも同じ値が入力されるため、ダブルトランスフォームが発生します。また、子階層にある「ctrlB」も一緒に移動してしまうため、このままの構成では実用的ではありません。

② 次に、「ctrlA」の Translate と「Rotate Pivot」によって発生しているダブルトランスフォームを修正します。
今回は、Translate の移動量を「Rotate Pivot Translate」で打ち消すことで、ダブルトランスフォームを解消していきます。
まず、multiplyDivide ノードを作成します。
「ctrlA」の Translate を multiplyDivide の input1 に接続し、input2 には「-1」を入力します。
そして、multiplyDivide の output を、「ctrlA」の「Rotate Pivot Translate」へ接続します。


これにより、「Rotate Pivot Translate」には Translate の逆方向の値が入力されるため、「ctrlA」の移動量が内部的に相殺されます。その結果、ダブルトランスフォームが解消され、オブジェクト位置を維持したまま Pivot のみを移動できるようになります。ただし、機能自体は完成していますが、コントローラ位置と Pivot 位置が一致していないため、操作時の視認性に課題があります。

③ 視覚的にわかりやすくするため、黄色のコントローラ自身が Pivot 位置へ配置されるように設定していきます。
まず、「ctrlA」を複製し、新しく作成したコントローラを「new_ctrlA」とします。
元の「ctrlA」はシェイプノードを削除し、Pivot 制御用のトランスフォームノードとして使用します。
そして、新しく作成した「new_ctrlA」を、実際に操作する黄色のコントローラとして使用します。

④ 「new_ctrlA」の Rotate を、「ctrlA」の Rotate に接続します。
次に、「new_ctrlA」の Translate を、「ctrlA」の「Rotate Pivot」に接続します。
先ほど②では、「ctrlA」の Translate を直接「Rotate Pivot」へ接続していたため、同一 Transform 内でダブルトランスフォームが発生していました。そこで、「Rotate Pivot Translate」を multiplyDivide ノードで相殺する構成にしていました。
しかし今回は、「new_ctrlA」と「ctrlA」を分離したことで、Translate と Pivot 制御が別 Transform となり、ダブルトランスフォーム自体が発生しなくなります。この構成では、先ほど作成した multiplyDivide ノードは不要となるため、削除して問題ありません。

これにより、黄色のコントローラ「new_ctrlA」を移動した位置が、そのまま Pivot の位置として機能するようになります。これで、Pivot 制御を 1 つにまとめたコントローラの完成です!

3.まとめ
コントローラが Pivot 位置に配置されることで、「コントローラを移動させた位置を中心に回転する」という挙動を、より直感的に理解しやすくなると思います。また、今回の設定を応用することで、「回転してほしい位置」と「スケールしてほしい位置」が異なる場合の制御にも活用できるため、非常に便利です。
今回の計算ノードには multiplyDivide を使用しましたが、floatMath を使用して同様の構成を作成することも可能です。ぜひ試してみてください!
ではまた!
※免責事項※
本記事内で公開している全ての情報について、その完全性、正確性、適用性、有用性等いかなる保証も行っておりません。
これらの情報のご利用により、何らかの不都合や損害が発生したとしても、当社は何らの責任を負うものではありません。
自己責任でご使用ください。
