歩行モーションなどを作る際に、モーションをミラーコピーして、さらにタイミングを半歩ずらしたかったので、作ってみた
今回調べたアニメーション系のMel
最初のキーフレームを取得
findKeyframe -timeSlider -which first;
最後のキーフレームを取得
findKeyframe -timeSlider -which last;
次のキーフレームを取得
findKeyframe -timeSlider -which next;
アニメーションの終了時間を取得
playbackOptions -q -maxTime;
キーフレームをタイミングをずらしてミラーコピーする
ざっくり書いたので結構荒いです。多分もっと行数減らせる^^;
一応仕様(自分用なので色々と決めうち(そのうちちゃんとするかも))
・引数でずらすフレーム数を指定
・最初に選んだオブジェクトから次に選んだオブジェクトにミラーコピー。(エラー処理してない^^;)
・ループ想定なので、最終フレームにキーを打った際は0フレーム目にも自動でキーを打つ
・なのでアニメーション開始は0フレーム
・終了フレーム数もちゃんと設定しておかないと動かない^^;
proc CopyKeyFrameMirror(int $moveTime){
// コピー先への加算時間
$AdditionalTime = $moveTime;
// 選択中のオブジェクトを取得
$name = `ls -sl`;
// コピー元のみを選択させる
select -r $name[0];
// 最初のキーフレーム
$firstKeyFrame = `findKeyframe -timeSlider -which first`;
// アニメーションの終了時間
$maxTime = `playbackOptions -q -maxTime`;
// 処理中の時間
$time = $firstKeyFrame;
while(1){
// コピー元の処理用の時間のタイムラインへ移動する
currentTime -edit $time;
// トランスフォームを取得
float $vals[];
$vals[0] = getAttr($name[0] + ".tx");
$vals[1] = getAttr($name[0] + ".ty");
$vals[2] = getAttr($name[0] + ".tz");
$vals[3] = getAttr($name[0] + ".rx");
$vals[4] = getAttr($name[0] + ".ry");
$vals[5] = getAttr($name[0] + ".rz");
// コピー先の時間を割り出す
$afterTime = ($time + $AdditionalTime) % $maxTime;
// コピー先の時間へ移動する
currentTime -edit $afterTime;
// トランスフォームを設定(ミラーのため一部マイナスで設定)
setAttr ($name[1] + ".tx") ((float)-$vals[0]);
setAttr ($name[1] + ".ty") ((float) $vals[1]);
setAttr ($name[1] + ".tz") ((float) $vals[2]);
setAttr ($name[1] + ".rx") ((float) $vals[3]);
setAttr ($name[1] + ".ry") ((float)-$vals[4]);
setAttr ($name[1] + ".rz") ((float)-$vals[5]);
//キーフレームを設定する
setKeyframe -breakdown 0 -hierarchy none -controlPoints 0 -shape 0 $name[1];
// コピー先の時間が0だったら最終フレームにもキーフレームを設定する
if( $afterTime == 0 ){
currentTime -edit $maxTime;
// トランスフォームを設定
setAttr ($name[1] + ".tx") ((float)-$vals[0]);
setAttr ($name[1] + ".ty") ((float) $vals[1]);
setAttr ($name[1] + ".tz") ((float) $vals[2]);
setAttr ($name[1] + ".rx") ((float) $vals[3]);
setAttr ($name[1] + ".ry") ((float)-$vals[4]);
setAttr ($name[1] + ".rz") ((float)-$vals[5]);
setKeyframe -breakdown 0 -hierarchy none -controlPoints 0 -shape 0 $name[1];
}
// コピー元の時間へ戻す
currentTime -edit $time;
// 次のコピー元の時間へ移動する
$time = `findKeyframe -timeSlider -which next`;
// 次のコピー先の時間が最初のフレームだったらループを抜ける
if( $time == $firstKeyFrame )break;
}
}