HumanIKで複数ターゲットからリグに一括でベイクする

この記事は[Maya Advent Calendar 2021](https://qiita.com/advent-calendar/2021/maya)の12日目の記事になります。

皆さんこんばんは。
AdventCalendarを立ち上げた本人です。

本人ですが、実はあまりMayaを触っておらずネタが無かったので、こちらの投稿からネタを貰うことにします。

https://twitter.com/JunkiTheJunkie/status/1450402188497354753?s=20

というわけで「HumanIKで複数ターゲットからリグに一括でベイクする」スクリプトを作ってみます。

この記事ではHumanIK サンプルを使用します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212052/30c3f05b-bdb8-3c65-6072-ba4152508702.png)

## 作戦
あまり検証に時間が取れないので、
少々泥臭いですが手っ取り早そうな**1キャラクタずつ順番にベイクするようなスクリプト**にしたいと思います。

なので、
1. シーン上に存在するキャラクタのリストを取得
2. ひとつめのキャラクタをUIでセット&ソースをなしにする
3. どうにかこうにか骨からリグにベイクする
4. 終わったら2と3をキャラクタの数だけ繰り返す

ような感じにすれば恐らく実現できるような気がします。

## キャラクタのリストを取得
さてどうすればそんなことが出来るのか。
少なくとも表面上はそんなコマンドがぱっとは見つからないのでアマゾンの奥地へと向かう必要がありそうな気配です。



･･･と思っていたら、偶然にも[Maya Advent Calendar 2018のとある記事](https://qiita.com/amanatsu-knit/items/8c66297b012d74f7438a#%E3%82%AD%E3%83%A3%E3%83%A9%E3%82%AF%E3%82%BF%E3%81%AE%E5%A4%89%E6%9B%B4)にヒントが隠されていそうです。

> 以下のコマンドでCharacterを変えることが可能です
```optionMenuGrp -e -v "Character1" hikCharacterList;
hikUpdateCurrentCharacterFromUI(); 
hikUpdateContextualUI();```

ふむ。 `optionMenuGrp `。
こいつでどうにか出来そうな予感。

早速[リファレンス](http://me.autodesk.jp/wam/maya/docs/Maya2010/Commands/optionMenuGrp.html)を覗いてみたら、いくつか使えそうなフラグが見つかりました。

```
-numberOfItems(-ni)		query
メニュー項目の数を返します。

-select(-sl)	int	create query edit
インデックスで項目を選択します。最初の項目が 1 になります。
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212052/1d84b3e6-3a49-87cd-c65d-6ab3a356a017.png)
ほう。キャラクタ数はメニューの項目数(※なしも含む)として取得できて、キャラクタ変更はインデックス指定が使えるのか。
これなら具体的なキャラクタ名の文字列が分からなくてもキャラクタ数を元にループさせてキャラクタを変更できそうですね。
これでひとまずキャラクタのリスト取得はクリアできそうです。


## UIの動的切り替え&ソースをなしに
これも運よく[Maya Advent Calendar 2018のとある記事](https://qiita.com/amanatsu-knit/items/8c66297b012d74f7438a#%E3%82%AD%E3%83%A3%E3%83%A9%E3%82%AF%E3%82%BF%E3%81%AE%E5%A4%89%E6%9B%B4)の中にヒントがありそうです。

[ここ](https://qiita.com/amanatsu-knit/items/8c66297b012d74f7438a#%E3%82%AD%E3%83%A3%E3%83%A9%E3%82%AF%E3%82%BF%E3%81%AE%E5%A4%89%E6%9B%B4)と[ここ](https://qiita.com/amanatsu-knit/items/8c66297b012d74f7438a#%E3%82%AD%E3%83%A3%E3%83%A9%E3%82%AF%E3%82%BF%E3%81%AE%E5%A4%89%E6%9B%B4)の情報を使えばなんとかなりそうなので、ひとまずクリアとしましょう（雑）

## 骨 -> コントロールリグへのベイク
HumanIKの場合、メニューから`ベイク処理 -> コントロール リグのベイク処理`を**ソースなし**にした状態で使用すると骨からリグに対してアニメーションをベイクすることが出来ます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212052/7e80ccf8-0a23-ef6e-5895-23d9ad24fcba.png)

実行してみると、以下のようなログが出力されます。

```
hikBakeToControlRig 0; hikSetCurrentSourceFromCharacter(hikGetCurrentCharacter()); hikUpdateSourceList; hikUpdateContextualUI;
```

ふむ、なんかこのコマンドを使えば

1. コントロールリグへのベイク
2. HumanIK UIの更新

までやってくれそうですね
あまり細かい事は気にせずこいつをスクリプトのパーツにしましょう

## スクリプトパーツの組み立て
さて、ここまで集まったパーツを組み立ててスクリプトを完成させてみましょう。

早速ですが完成したスクリプトがこちら

```
{
    // 1. シーン上に存在するキャラクター数を取得
    int $hikCharacterCount = `optionMenuGrp -q -ni hikCharacterList`;
    for($i=2;$i<=$hikCharacterCount;$i++){ // index 0は範囲外、1がなしなので不細工だけど2からループスタート
　　　　// 2. キャラクターを$i番目に変更
        optionMenuGrp -e -sl $i hikCharacterList;
        hikUpdateCurrentCharacterFromUI(); 
        hikUpdateContextualUI();
        // 3. ソースをなしに変更
        optionMenuGrp -e -sl 1 hikSourceList; // 同じくindex 0が範囲外、 index 1が なし
        hikUpdateCurrentSourceFromUI;
        hikUpdateContextualUI();
        // 4. コントロールリグにベイク
        hikBakeToControlRig 0; 
        hikSetCurrentSourceFromCharacter(hikGetCurrentCharacter()); 
        hikUpdateSourceList;
        hikUpdateContextualUI;
    }
}
```

はい、こんだけです。
文字列指定じゃないので多分英語UIでも動くと思いますが試してないので責任は持てません。


やってることはコメントに書いてある通りです。
案外簡単に出来て安心しました！！！（現在2021/12/11 22:48）

## おわりに
今年も懲りずにMaya Advent Calendarを立ち上げたわけですが、さすがにもう枠が埋まらなくなってきましたねぇ。
むしろ今までよく埋まってたなというべきか、昨今のトレンドなDCCツールと比べてネタが少ないのでしょうがないことなのでしょう。
なので、今年からはあまり気負わず、完走も特に目指さずマイペースにAdvent Calendarを楽しんでいければと思っております。

明日の記事はまだ埋まっておりませんので、気が向いた方は是非参加してみてください！