本連載は、筆者のオリジナルキャラクター『流流(るる)』を題材に、リアルタイム向けのシンプルなリグとモーション制作について紹介します!
今回でボディリグの主要要素をひと通り組み上げます。前回よりもさらに小難しい説明が増えてきますが、肩の力を抜いてお付き合いください。
Topic 1:頭の World/Local 切り替え
前回、胴体を動かしても頭の姿勢が変わらないようにセットアップしたのを覚えていますでしょうか。
逆に、頭が胴体に素直に追従してほしい場合もあります。例えば、後ろ回し蹴りや宙返りなどの動きをつくる場合です。今のリグ構造だと身体の回転に合わせて頭も動かす必要があり、試行錯誤が長引くほどアニメーションの所要時間が増えてしまうことになります。
そこで、今回は頭の追従モードを切り替えるしくみを作成します。
以下のようにモードの種類を定義します。
- World
頭が胴体の姿勢の影響を受けない。
- Local
頭が胴体の姿勢の影響を受ける。
前回セットアップした構造は「World」モードになります。今から頭の World/Local を切り替えられるようにセットアップを行います。
切り替え方法
前回の Topic 5:頭のリギング を振り返りながら進めていきましょう。
胴体の姿勢の影響を受けないよう、頭のコントローラセットを Neck 階層から外に出し、位置だけ首の位置に拘束するように(=World モード)セットアップしました。ということは、さらに方向も追従させれば Local モードが実現できそうです。
[Dvr_C_Head → Dvn_C_Head]の順に選択、OrientConstraint で方向を拘束します。
頭が胴体の姿勢の影響を受けるようになりました。つまり「Local」モードの状態です。ここからどうやって World/Local モードを切り替えるかが問題です。
コンストレイントノード「Dvn_C_Head_orientConstraint1」を選択し ChannelBox を確認すると「Dvr C Head W0」というアトリビュートがあります。これはコンストレイントのウェイト値です。この値が 0 になると OrientConstraint の影響が消える=元の World モードに戻る ということになります。
つまり、World/Local を切り替えるには、「Dvn_C_Head_orientConstraint1」の「Dvr C Head W0」の値をリグで制御できれば良さそうです。
スイッチ用のコントローラ作成
さて、リグから World/Local モードを切り替えるにはアトリビュートが必要になります。このような追加アトリビュートをどこに実装するべきか?筆者も毎度悩むところです。
1つは、シンプルに頭のコントローラ「Con_C_Head」に直接追加してしまうという考え方があります。
コントローラが増えないのでリグの見た目がスッキリしますし、機能が部位に紐づいているのである意味直感的に編集できそうですが、リグを初めて触る人にとってはお目当ての機能を探しにくいかもしれません。複数部位のモードを一度に切り替えたい場合は、コントローラ選択の手数が増えてしまうでしょう。
今回はわかりやすく専用コントローラを作成してみましょう。今後、他の追加アトリビュートも同じコントローラにまとめていきます。
スイッチ用のコントローラ「Con_Switch」を作成し、これまでのお作法通り、オフセットノード「Off_Switch」にペアレントします。配置は自由ですが、あくまでサブコントローラなので、普段のアニメーション作業で邪魔にならない場所が良いと思います。例えば腰の後ろあたりなどが良いかもしれません。位置を決めたら Con_C_Waist にペアレントします。これでキャラクターの動きにも追従してくれます。
カスタムアトリビュートを追加する
モードを切り替えるアトリビュートをコントローラに追加します。ユーザーが任意で追加するアトリビュートを「カスタムアトリビュート」と呼びます。
Con_Switch を選択した状態で、[Modify → Add Attribute]でカスタムアトリビュート追加ウィンドウを開き、各項目を以下のように設定します。
- Long Name/名前
Head_Local
- Data Type/データ型
Float ※無段階調整できる浮動小数点型に
- Minimum/最小値
0
- Maximum/最小値
1
- Default/初期値
0 ※好みで 0(World)か 1(Local)を設定
[Add]を実行すると、Con_Switch に「Head_Local」というカスタムアトリビュートが追加されます。
NodeEditor でアトリビュートを接続する
カスタムアトリビュート「Head_Local」でコンストレイントのウェイト値を制御するために、「NodeEditor」を使用してアトリビュート同士を接続します。NodeEditor は[Windows → Node Editor]で開きます。
以下に NodeEditor の図解をまとめます。
※詳しい使用方法は Maya ヘルプをご確認ください。
「Con_Switch」「Dvn_C_Head_orientConstraint1」の2つをエディタに表示し、コントローラのカスタムアトリビュート(Head_Local)からコンストレイントのウェイト値(Dvr C Head W0)にグラフを接続します。これで切り替えスイッチのセットアップは完了です。
Topic 2:腕の IK/FK 切り替え
「身振り手振り」という言葉があるように、「腕」は表情に次いで感情表現を司る非常に重要な部位です。
日常演技だけでなく格闘アクションにとっても腕は重要で、手技だけでも非常に多くの技がありますし、同じ立ち方でも腕の配置や角度次第で多様な構えを表現することができます。キャラクターの個性付けにも欠かせません。
それだけ重要な「腕」のリグにはアニメーターの要望に柔軟に応えられるような多様性が求められ、ゆえに様々な機能が集約されやすい部分です。このチュートリアルでは、第2回で紹介した「IK/FK」を切り替える機能を実装してみましょう。
IK/FK ブレンド
IK/FK 切り替えリグのセットアップ手法は様々ですが、ここではよく使われるジョイントチェーンを用いたブレンド方法を解説します。IK と FK をそれぞれ別のジョイントチェーンに対してセットアップし、両者のブレンド(混合)結果をメインのジョイントチェーンに反映させるという方法になります。
アトリビュートの作成
まずは IK/FK を切り替えるためのアトリビュートを作りましょう。本チュートリアルでは IK をベースに組んでいきますので、FK モードに切り替えるためのアトリビュートが必要になります。
Topic.1 で作成したスイッチコントローラ「Con_Switch」に、カスタムアトリビュート「L_Arm_FK」を追加します。カスタムアトリビュート作成オプションはアトリビュート名以外、「Head_Local」と同じ設定でOKです。また、今は左側のセットアップのみ解説しますが、後々、右側用のカスタムアトリビュート「R_Arm_FK」も必要になることをお忘れなく。
ブレンド用ジョイントチェーンを作成する
左腕のジョイントチェーン「Jnt_L_Arm1」「Jnt_L_Arm2」「Jnt_L_Hand」を[Ctrl]+[D]で複製して3セット作成し、それぞれ役割がわかるようにリネームします。なお、バインドスケルトンと区別するため、ノード識別子は「Jnt」→「Mid」に変えています。
▼メインジョイントチェーン (最終結果反映用)
Mid_L_Arm1
└ Mid_L_Arm2
└ Mid_L_Hand
▼IK ジョイントチェーン
Mid_L_Arm1IK
└ Mid_L_Arm2IK
└ Mid_L_HandIK
▼FK ジョイントチェーン
Mid_L_Arm1FK
└ Mid_L_Arm2FK
└ Mid_L_HandFK(※)
※FKセットアップに必要なのは Arm1、Arm2 だけなので Hand は削除しても良いのですが、ジョイントチェーンの見た目がわかりやすいようにあえて残しています
Utility ノードでジョイントの回転値をブレンドする
頭の World/Local 切り替えは単純なアトリビュート接続でしたが、IK/FK の値を混ぜるために「Utility ノード」を中継して接続します。
ここでは「blendColors」という Utility ノードを使います。その名の通り、本来は2つのカラー[R,G,B]を混ぜるノードなのですが、[R,G,B]の3値を[X,Y,Z]として扱い、IK/FK ジョイントの回転値を混ぜることができます。
blendColors の各アトリビュートに以下の要素を接続します。
- Blender
Color1/Color2 のブレンド割合。例えば 0.6 なら[Color1:60%/Color2:40%]の値が Output へ送られる。
Con_Switch の L_Arm_FK を接続する。
- Color1
入力値1。FK ジョイントの Roate を接続する。
- Color2
入力値2。IK ジョイントの Roate を接続する。
ジョイントを直接動かして確かめてみましょう。L_Arm_FK の値によって、IK/FK ジョイントへの影響結果が変わるのを確認できるかと思います。
動作確認後は、必ずジョイントをデフォルト姿勢に戻しておいてください。
これで IK/FK 切り替えの処理自体はできたので、各ジョイントにコントローラをセットアップしていきます。
IKセットアップ
前回の脚のセットアップと同じように、IK ジョイントチェーン Mid_L_Arm1IK~Mid_L_HandIK に対して「IKハンドル」を設定します。
IK コントローラセットを作成し、IK ハンドルを「Con_L_ArmIK」の子にペアレントします。誤って選択してしまわないように非表示にしておきます。
関節の向きを制御する「ポールベクター」用のコントローラを作成し、IK ハンドルに対して PoleVectorConstoraint を設定します。ポールベクターは肘関節から真っ直ぐ後ろに下げた場所に配置しましょう。脚のセットアップと同じ要領でOKです。
Con_Switch.L_Arm_FK を 0 にした状態(=IKモード)でコントローラを動かし、動作確認できたら腕の IK セットアップは完了です。腕のリグはいったん、身体の階層外に出したままでOKです。
FKセットアップ
次は FK セットアップです。こちらは単純に Arm1、Arm2 に対してそれぞれコントローラを作り、OrientConstraint するだけです。
Con_Switch.L_Arm_FK を 1 にした状態(=FKモード)でコントローラを動かし、腕が正しく動くことを確認できたら腕の FK セットアップは完了です。
コントローラの表示切り替え
腕のリグ要素が揃いましたが、今のままでは IK/FK 両方のリグが表示されたままで扱いづらいです。IK/FK モードに応じて表示を切り替えるようにしましょう。
ここでも NodeEditor を使用し、Con_Switch.L_Arm_FK の値を各リグの visibility へノード接続します。切り替えアトリビュート「L_Arm_FK」からFK リグに対してはアトリビュートを直接繋ぐだけでOKですが、IKリグは逆の挙動である必要があります。そこで「Reverse」という、値を反転してくれる Utility ノードを使います。
IK/FK モードの切り替えと同時に、各リグの表示も適切な表示に切り替わることが確認できたら、コントローラ表示切り替えの設定は完了です。
Topic 3:手首のセットアップ
手首自体はシンプルな FK セットアップになります。Con_L_Hand のコントローラセットを作成し、Mid_L_Hand を OrientConstraint します。
手首の位置にコントローラを追従させる
手首をどのように腕に追従させるかは好みによると思います。リグによっては「位置」しか追従しないものも多いですが、筆者の場合、「向き」も追従するように組むことが多いです。本チュートリアルでは解説を省いていますが、腕IKを World モードにしたときに手首も World になってほしいと考えているためです。
ということで、今回は手首の向きが腕に追従するセットアップを解説します。
まず、Mid_L_Arm2 の子に Transform ノード「Dvr_L_Hand」を作成します。姿勢は Mid_L_Hand に合わせます。次に、Off_L_Hand の親に Transform ノード「Dvn_L_Hand」を作成し、Dvr_L_Hand を ParentConstraint します。
IKコントローラを動かし、動作確認できたら手首のセットアップは完了です。
Topic 4:指のセットアップ
人型のCGキャラクターにおいて、指は顔に次いで複雑な部位です。中手骨(手の甲の骨)を除いても片手だけで15ジョイントも必要になります。これら1つずつを動かしてアニメーションを作成するのは非常に大変なので、指をまとめて制御できるリグを作ってみましょう。
指のコントローラセット作成
各指のコントローラセットを作っていきますが、前述した一括制御の準備として、オフセットノード(Off_)とコントローラ(Con_)の間にノード(Dvn_)を追加する必要があります。
▼コントローラセットの構造
Off_L_Finger〇〇
└ Dvn_L_Finger〇〇
└ Con_L_Finger〇〇
Off、Dvn、Con の3つで1セット。これら3つの姿勢はまったく同じにします。
いつもより1ノード多い以外は普通の FK セットアップです。ジョイントをコントローラに OrientConstraint するだけです。
Off と Con の間に挟んだ Dvn ノードは、次に説明する一括制御機能で制御するためのノードになります。
ドリブンキーの解説
Maya の「ドリブンキー」という機能を使用し、素早く手をポージングできる一括制御リグを作成します。ドリブンキーとは、あるアトリビュートを使って別の複数アトリビュートを動かすことができる機能です。
ドリブンキー機能において両者は以下のように呼ばれます。
- Driver
動かす側のアトリビュート
- Driven
動かされる側のアトリビュート。複数設定可能
ドリブンキー用コントローラの作成
「Driver」になるコントローラを作成します。「Con_L_FingerAll」のコントローラセットを作成し、Con_L_Hand の子にペアレントします。
Con_L_FingerAll をどのように動かすかはアニメーターの好みによりますが、今回は Translate を使った DrivenKey とします。シンプルに指全体がグーパー開閉するしくみを作ってみましょう。
ドリブンキーの設定
Animation メニューセットの[Key→Set Driven Key→Set...]からドリブンキーを設定するためのウィンドウを開きます。
ドリブンキーで制御したいオブジェクトを選択して[Load Driver/Driven]を押すと、それぞれのエリアにオブジェクトを登録できます。左半分にオブジェクト名、右半分にそのオブジェクトがもつアトリビュート一覧が表示されます。
Driver には Con_L_FingerAll を登録します。
Driven には Dvn_L_Finger〇〇 を全て登録します。これは前項の指セットアップで追加した Dvn ノードになります。各指のコントローラ(Con)を直にドリブンノードに登録しない理由は、ドリブンキーで Driver に設定されたアトリビュートは直接動かせなくなってしまうためです。指を個別に制御できるように、コントローラ自体は自由にして親ノード(Dvn)に対してドリブンキーを設定するというわけです。
リストから Driver/Driven アトリビュートをそれぞれ選択し Key を実行すると、現在の値でアトリビュート間の関連付けが作成されます。例えば「Con_L_FingerAll を X軸にこれだけ動かしたら指がこれだけ曲がる」といった関連付けをしていくことになります。
まずは、何も動かしていない初期状態のポーズにドリブンキーを設定します。
以降は
1.Driver/Driver を任意の値に動かす。
2.DrivenKey を設定する。
…のくり返しで、お好みのポーズでドリブンキーを設定していきます。
Topic 5:肩のセットアップ
最後に肩をセットアップします。
肩自体は普通にFKセットアップです。「Con_L_Shoulder」のコントローラセット作成と、ジョイントとの OrientConstraint、いつもの流れになります。
肩を動かしても腕の角度が変わらないようにする
腕のコントローラ群を肩に普通にペアレントした場合、腕全体が肩の挙動の影響を受けます。ポージングのシルエット作りや演技において肩は非常に重要で、モーションを詰めていく上で調整必須な部位になりますので、肩を動かす度に腕の姿勢が変わってしまうのは都合が悪いです。
そこで、腕のリグを Shoulder 階層から外し、位置だけ参照するようにリギングします。頭の World セットアップと同じような流れです。
腕のリグ全体を包む親ノード「Dvn_L_Arm1」を作成。姿勢は二の腕 Jnt_L_Arm1 に合わせます。その子に腕のリグ要素(IK、PV、FK、Hand、Mid)を全て入れます。
次に、Con_L_Shoulder の子に Dvn_L_Arm1 を作成し、Dvr_L_Arm1 を Dvn_L_Arm1 に PointConstraint します。
肩を動かしても腕全体は位置のみ追従し、角度は維持するようになりました。
今回のまとめ
今回のまとめになります。
・リグの挙動に唯一の正解はない。複数モードを用意して切り替えよう。
・カスタムアトリビュートを使いこなそう。
・NodeEditor は Maya リギングの必須ツール。
・複雑で動かすのが大変な箇所は、 DrivenKey で一括制御できる。
リギングの解説はどうしても文章が長くなりがちで、おそらく初心者の方は記事を読んだだけでは理解しきれない部分も多かったと思いますが、何となく一連の流れが掴めてもらえたらひとまずOKです。
また、Maya 特有の機能解説がいくつかありましたが、Blender など他DCCツールにも類似機能、実現手段はありますので、本記事をヒントにぜひ調べてみてください。
次回はリギングの小話や、フェイシャルリグについて解説したいと思います。引き続きどうぞよろしくお願いします。
※記事のご感想、リクエストなどお待ちしています!
Lee
ゲーム会社でコンシューマタイトルの開発に携わる傍ら、自主制作ゲームの進捗やCG作品などをTwitterで日々ゆるく発信している。インディーゲーム『ヤマふだ!』シリーズのグラフィック全般を担当。
X(旧Twitter):@leedoppo
TEXT_Lee
EDIT_小村仁美 / Hitomi Komura(CGWORLD)