チュートリアル / 読んで触ってよくわかる!Mayaを使いこなす為のAtoZ
第73回:コンストレイントは○○だと考えるとわかりやすいかも?

  • Maya
  • アニメーション
  • コラム
  • チュートリアル
  • データ
  • 学生・初心者
コンストレイントは○○だと考えるとわかりやすいかも?

アニメーションやリグを作っているとコンストレイントを使うときがあります。Point ConstraintやAim Constraintなどいろいろなコンストレイントがあります。

Mayaでアニメーションをつけ始めた頃、この「コンストレイント」と言うものがとても厄介だったことを思い出します。

「手を机に固定したい時にコンストレイントを使うんだよ」と教わっても、コンストレイントの種類の違いもよくわからなければ、なぜ固定できるかもいまいちピンとこない…。
動きを「拘束」できるけど、具体的に何が起きているかよくわからない感じです。

CGは数値を扱っているので見た目に何が起きているかわかりにくく、コンストレイントを理解するのはなかなか大変です。このあたりでつまずいたり、上手く使えなくて毎回行き当たりばったりでいろいろなコンストレイントを試したりしている方もいると思います。

今回は、ちょっと違う視点でコンストレイントを見ることで理解を深めてみましょう!

コンストレイントは「値の変換装置」と思えばOK

風車を回して電気を作る。
太陽光で電気を作る。
電気を使ってお湯を沸かす。
ガスを使ってお湯を沸かす。

これらは皆さんが日常的に見ていて、よく理解している現象ですよね。
理科の授業で聞いた気がするアレです、電気の力が熱に変わるとかいう、エネルギーの変換というものです。

コンストレイントの説明は難しい用語が並んでいるせいで、気づいたらまぶたが落ちがちですが、要はエネルギーの変換と同じで「○○を△△に変換する機能」と考えればわかりやすくなります。
コンストレイントは「値の変換装置」として使えば良いのです。

具体的な意味合いが掴みにくいでしょうから、まずは例を紹介します。
例えば、Aim Constraintはオブジェクトを別のオブジェクトに向けます。

例えば、Aim Constraintはオブジェクトを別のオブジェクトに向けます。

指定した位置に向くように回転値が変化します。これは「位置情報を回転に変える」ということを行っています。位置情報から回転値を生成しているわけです。位置と回転の値は直接関係はないですが、コンストレイントを使うと変換できるのです。

先程、コラムを書く景気付けにコーヒーを沸かしたのですが、「お湯」が欲しいので「電気」で沸かしました。同じ感覚で、「回転の値」が欲しいので「位置」から作るのがAim Constraintです。

キャラクタの目を別のオブジェクトに向けたいとき、オブジェクトの位置から回転値を作りたいのでAim Constraintを使う、という感じですね。

「何の値がほしいか?」「どの値が使用可能か?」がわかれば、どのコンストレイントを使えばよいか簡単にわかるようになります。

変換装置としてのコンストレイント

それぞれのコンストレイントが何を変換するか見ていきましょう。

Aim Constraintは「位置」を「回転」に変換します。
IKも実は「位置」を「回転」に変換する装置です。Aimと同じように使えます。

IKはジョイントが腕のようにつながっていなくても使用できます。次の図では一本の骨(二つのジョイント)にIKを作って回転させています。

変換装置としてのコンストレイント

他のコンストレインは、当たり前のように聞こえますが、次のように変換をします。

Point Constraintは「位置」を「位置」に変換します。
Orient Constraintは「回転」を「回転」に変換します。
Scale Constraintは「スケール」を「スケール」に変換します。

コンストレインの特徴として「階層の親を無視して、必ず変換された回転・位置」になりますので、「位置」を「位置」に変換するといっても、実際にはそれぞれの階層に合った値に変換されています。

コンストレイントの使い方を工夫すると、変換の内容がちょっと変わります。
例えばジョイントの先端にロケーターをつけた場合、ジョイントが回転するとロケーターの位置も変わります。

ジョイントの先端にロケーターをつけた場合、ジョイントが回転するとロケーターの位置も変わります。

「回転」が「位置」に変換されたことになります。

Parent Constraintは「位置」を「位置」に、「回転」を「回転」に変換しますが、親子構造を擬似的に作って動かしますので、オブジェクト同士を離して回転させると「回転」が「位置」に変換されます。

Parent Constraintは「位置」を「位置」に、「回転」を「回転」に変換しますが、親子構造を擬似的に作って動かしますので、オブジェクト同士を離して回転させると「回転」が「位置」に変換されます。

(もしコンストレイントするオブジェクト同士が同じ位置にあるなら、Parent ConstraintはPoint/Orient Constraintしたのと同じ結果になります。)

まとめると次のようになります。

まとめ

手をテーブルに付ける

キャラクタのアニメーションをさせていて、手をテーブルにつけることを考えてみましょう。

キャラクタのアニメーションをさせていて、手をテーブルにつけることを考えてみましょう。

手を付けるということは、手の位置と回転を、テーブルに固定することです。
「位置を固定する方法はどれか?」と表を見ると、位置の列に矢印が飛んできています。PointとParentから矢印が来ているので、このどちらかが使えることがわかります。
「回転を固定する方法は?」と表を見ると、回転の列にOrient、Aim、IK、Parentの矢印が来ていることがわかります。

それではということで、テーブルと手を選択して、PointとOrientのコンストレイントを作ると、無事に手がテーブルに固定されます。

テーブルと手を選択して、PointとOrientのコンストレイントを作ると、無事に手がテーブルに固定されます。

ただしテーブルが回転すると、回転の値を手に伝えますが、「回転→位置」には変換しないため、次のキャプチャのように手が離れてしまいます。

テーブルが回転すると、回転の値を手に伝えますが、「回転→位置」には変換しないため、次のキャプチャのように手が離れてしまいます。

Parent Constraintで位置と回転を固定すれば、テーブルの位置が変わっても手がついてきます。
テーブルの「回転」が手の「位置」に変換されるため、親子構造があるように手が回転してくれます。

Parent Constraintで位置と回転を固定すれば、テーブルの位置が変わっても手がついてきます。

どのコンストレイントを使用しても、コンストレイントは階層を無視して、手の親の位置がどこにあっても強制的にテーブルにつきます。

リグを作るときの役立て方

この考え方はリグを作るときにも便利です。
とにかくリグは、位置や回転の変換しまくり機械ですので、何をすればよいか混乱した時に上の図が役に立ちます。

ちょっとややこしいですが、
「肩の回転を位置で制御する」リグを作るとします。腕は既にIKが張られているとします。

「肩の回転を位置で制御する」リグを作るとします。腕は既にIKが張られているとします。

位置から回転値を作りたい…というわけで上の表を見てみると、位置から回転に矢印が向かうのはAimとIKです。
どちらを使ってもよいのですが、まずはAim Constraintを使うことにします。
位置を制御するためのロケーターと肩の骨を選択してAim Constraintを作ります。

位置を制御するためのロケーターと肩の骨を選択してAim Constraintを作ります。

IKを使う場合はどうでしょうか?
単に肩の骨の根本と先端に対してIKを作ればOKです。

IKを使う場合は、単に肩の骨の根本と先端に対してIKを作ればOKです。

Rotate-Plane SolverとしてIKを作れば、骨のねじれをポールベクターやIKのtwistの値で行えるのでラクです。

布をジョイントにベイク

ゲーム制作では、布のシミュレーションをジョイントの動きにベイクしたいときがあると思います。
コンストレイントが変換装置だとわかれば、これも簡単にできます。

布のシミュレーションは頂点の位置をシミュレーションします。
つまり、位置情報を得られます。
ジョイントには回転情報が欲しいので、表を見てみるとAimとIKが使えることがわかります。

ではIKでシミュレーションをジョイントの回転値に変換してみましょう。

次のように布とジョイントを作るとします。
IKをジョイント一本ごとに作ります。

布とジョイントを作るとします。IKをジョイント一本ごとに作ります。

次に、IKが乗っかっている布の頂点とIK間にPoint On Poly Constraintを作成します。Point On Polyは選択した頂点にコンストレイントさせられます。

で、布をシミュレーションすれば、「頂点の位置」が「IKの位置」となり、「IKの位置」が「ジョイントの回転」に変換されます。

布をシミュレーションすれば、「頂点の位置」が「IKの位置」となり、「IKの位置」が「ジョイントの回転」に変換されます。

段々とこの話に実用的なニオイがしてきましたでしょうか?
コンストレイントが変換装置であるとわかると、こんな応用がいろいろなところで思いつくようになります。

リグを作るときの役立て方(座標の変換)

最後に上級者向けの少しややこしい話ですが、コンストレイントは座標変換に使用できます。

コンストレイントされるものに親があるとき、その親の位置を原点とした値に変換できます。

例えばエクスプレッションを使ってキャラクタの重心を計算するとします。
足や手の位置の平均値を重心とする場合、手足のワールド座標が必要です。

エクスプレッションを使ってキャラクタの重心を計算するとします。足や手の位置の平均値を重心とする場合、手足のワールド座標が必要です。

エクスプレッションはobject.translateの形式で記述してオブジェクトの位置をとれますが、ワールド座標は直接取れません。

そのためにコンストレイントを使って座標を変換します。

ロケーターを作り、手にコンストレイントします。
ロケーターに親がなければ、ロケーターのtranslate値は「手がワールド座標にあるときの位置」になります。

ロケーターを作り、手にコンストレイントします。ロケーターに親がなければ、ロケーターのtranslate値は「手がワールド座標にあるときの位置」になります。

エクスプレッションはこのロケーターのtranslate値を使うことで、無事に手足のワールド座標値を得られます。

階層をまたいだ値の変換の例として、例えばキューブにコーンがPoint Constraintでくっついてくるようにします。コーンの親にグループをつけると、親グループを移動してもコーンはキューブの位置にとどまります。でもコーンのTranslate値はどんどん変わって、親グループを原点としたときの数値になります。

つまり同じ位置でも、階層によって座標の値が変わります。
これをマニュアルで計算しようとするとマトリクスの計算が出てくるのですが、コンストレイントを使えばそういった知識がなくても手っ取り早く座標変換ができます。

まとめ

「コンストレイントはオブジェクトを制約・拘束する機能」とはじめに聞くと、拘束って何?穏やかじゃないねーと、馴染みにくい距離感を感じてしまうことでしょう。

コンストレイントは単に「位置」や「回転」を変換する装置とわかれば、より使いこなすことができるようになります。

もし作業をしていて、どのコンストレイントを使えばいいのやら?となったときは、ぜひ表を参考にしながら欲しい値に変換する方法を考えてみてもらえればと思います。

製品購入に関するお問い合わせ
オートデスク メディア&エンターテインメント 製品のご購入に関してご連絡を希望される場合は、こちらからお問い合わせください。