HumanIKをコマンドで操作する

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

平成最後のアドベントカレンダー記事はみんな大好きHumanIKをコマンドのみでUI操作するTIPSの紹介をして締めくくりたいと思います。
TIPSといっても興味本位で調べたことが大半なので少々退屈な記事だとは思いますが、ご容赦ください笑

## 環境
- Windows10
- Maya2018

## キャラクタの変更
![image.png](https://qiita-image-store.s3.amazonaws.com/0/212052/dfbc16da-697c-d88f-a3b0-bf08721edaf8.png)

まず最初はキャラクタを変更してみます
以下のコマンドでCharacterを変えることが可能です

```
optionMenuGrp -e -v "Character1" hikCharacterList;
hikUpdateCurrentCharacterFromUI(); 
hikUpdateContextualUI();
```

一行目に文字列で指定したキャラクタに変更することができます。
この辺りはヒストリにも表示されるので知ってる人も多いかもしれませんね

ちなみに3行目の`hikUpdateContextualUI();`というコマンドはHumanIKのUIを更新するためのものです。
コマンドでHumanIKの値を変更するだけだとUIが更新されないので、コマンドで何かを変更するたびに実行する必要があります。


## ソースの変更
![image.png](https://qiita-image-store.s3.amazonaws.com/0/212052/3f88a7bd-b392-1169-6d4e-c84a0ac4d073.png)

次はソースを変更してみます
HIKはリターゲットが非常に便利なのでコマンド操作も覚えておくと良いことがありそうですね

```
optionMenuGrp -e -v " コントロール リグ" hikSourceList;
hikUpdateCurrentSourceFromUI;
hikUpdateContextualUI;
```

これもキャラクタと同じく1行目でソースを文字列で指定します。
注意点は `" コントロール リグ"` や `" スタンス"`のように、**ソース名の先頭に半角スペース**を入力する必要があるようです。
HumanIKらしい奥ゆかしい仕様です

## キャラクタ定義を作成
![image.png](https://qiita-image-store.s3.amazonaws.com/0/212052/e726f7d8-af0e-2242-0263-1616a98f1a94.png)
この章はリグログ様の[【Maya】HumanIKをスクリプトで！](http://rigglog.sakura.ne.jp/db/2016/06/28/%E3%80%90maya%E3%80%91humanik%E3%82%92%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%97%E3%83%88%E3%81%A7%EF%BC%81/)という記事をとても参考にしました

ここではリグログの記事内での流れを~~パク~~リスペクトしつつ、少しだけ掘り下げて書いてみます。

### 1. キャラクタの作成
以下のコマンドで定義用のキャラクタを作成します。

```
hikCreateDefinition()
```

特に何もしなければ `"Character1"` という名前で作成されます。
ではCharacter1以外の名前で作成するには？
キャラクタ名は後で変えることも可能なので特に気にする必要はないかもしれませんが一応調べてみます。

まずはwhatIsコマンド。

```
whatIs hikCreateDefinition;
// 結果: Mel procedure found in: C:/Program Files/Autodesk/Maya2018/scripts/others/hikDefinitionOperations.mel //
```

`hikDefinitionOperations.mel` というファイルの中に定義されているらしいので探してみると・・・


```
global proc hikCreateDefinition()
{
	// Create the new character -- pass in the name hint
	hikCreateCharacter( "Character1" );

	hikUpdateCharacterList();	// update the character list
	hikSelectDefinitionTab();	// select and update appropriate tab
}
```

ありました。
このプロシージャの中の `hikCreateCharacter( "Character1" );` の部分を `hikCreateCharacter( "test" );` に変えて実行してみると・・・

![image.png](https://qiita-image-store.s3.amazonaws.com/0/212052/23837284-6712-b8c2-58d5-7169c61fb4c8.png)

無事testという名前でキャラクタが作成されましたね
(4Kディスプレイで起動しているためUIが崩れていますが、それもまたHumanIKの可愛いところです)

### 2. 定義付け
試しに手動で `Character1_Hips` ジョイントをキャラクタの `Hips` オブジェクトに定義付けしてみると、以下のようなヒストリが出ます。

```
setCharacterObject("Character1_Hips","Character1",1,0);
```

どうやらこのコマンドを各ジョイントの数だけ実行すれば定義付けができるようです。

1つ目の引数がジョイント名、2つ目の引数がキャラクタ名。
では3つ目は？
これはリグログでも解説されているように、3つ目の引数「1」がキャラクタのHipsに該当します。
Maya2018のHumanIKだと0~211の番号に対してそれぞれオブジェクトが割り当てられているようです。

```
0 :Reference
1 :Hips
2 :LeftUpLeg
3 :LeftLeg
4 :LeftFoot
5 :RightUpLeg
6 :RightLeg
7 :RightFoot
8 :Spine
～～～～～～～～～
中略
～～～～～～～～～
206 :LeafRightUpLegRoll5
207 :LeafRightLegRoll5
208 :LeafLeftArmRoll5
209 :LeafLeftForeArmRoll5
210 :LeafRightArmRoll5
211 :LeafRightForeArmRoll5
212 :　　　　　　　　　　　　　// ここから先の番号にはなにも割り当てられていません

"""
リグログ様で紹介されていた以下のスクリプトを利用して表を作成しました
for ($i = 0; $i < 212; $i++){
    $name = GetHIKNodeName($i);
    print ($i + " :" + $name + "\n");
}
"""
```

では、 `setCharacterObject()` の4つめの引数の意味はなんなのでしょう？

```
whatIs setCharacterObject;
// 結果: Mel procedure found in: C:/Program Files/Autodesk/Maya2018/scripts/others/hikDefinitionUtils.mel // 
```

`hikDefinitionUtils.mel` というファイルに定義されているようですね
覗いてみましょう

```
// TODO : Rename the call to setCharacterObject in the Characterization Tool plug-in 
// and delete the old setCharacterObject() proc
global proc setCharacterObject( string $mayaNode, string $hikCharacterNode, int $pNodeCount, int $deletingBone )
{
	hikSetCharacterObject( $mayaNode, $hikCharacterNode, $pNodeCount, $deletingBone );
}
```

おっと、どうやらこのコマンドはリネーム予定のようですね
HumanIK関連のプロシージャには接頭辞に`hik`をつける計画の途中でしょうか？
いや～HumanIKの歴史を垣間見たようで感慨深いですね

もとい。

4つ目の引数は`$deletingBone` という名前のようです。
骨を消すのでしょうか？（英語力ゼロ）

コメントや処理内容を読んでみたところ、どうやら骨が削除されていたりした場合のためにいち早くチェックするためのもの？
のようです。（詳しくは理解できていないので間違っていたらご指摘ください）

```
// Bone is going away, no need to clear the connections. We make 
	// this check early so that we don't do operations like finding
	// the control rig on a bone that is about to be deleted.
	if ( $deletingBone )
		return;
	....
```

こういった操作をしたい場合は恐らくシーン内に使用する想定のジョイントが存在する前提だと思いますので、4つ目の引数は0でも大丈夫そうですね

### 3. ロック・コントロールリグの作成

定義付けが完了したら以下のコマンドでロックができます

```
hikCharacterLock("Character1",1,1);
```

すかさずコントローラを作成します

```
hikCreateControlRig;
```

完成！
![image.png](https://qiita-image-store.s3.amazonaws.com/0/212052/afca0393-936a-4f48-7799-3353f6bc3afd.png)

## おまけ
最新版のMaya2018だと解決しているようですが、
アップデートされていないMaya2018でHumanIKにアニメーションを付けタイムスライダを動かすとMayaがクラッシュする不具合があります。(`MAYA-91100 HIK : Crash when playback animation`)

プレーンなMaya2018でHumanIKを動作させたい場合は以下のコマンドを実行することで回避できるようです。

```evaluator -en 0 -n hik```

## おわりに
後半はもはやリグログ様の記事をただなぞっただけのような内容になってしまいました・・・！

実はMayaAdventCalendar24日目の記事が@3dcgbookさん（リグログの中の人）の記事だったのですが、文末にリグログが年内閉鎖という報告があり衝撃を受けました・・・！
今までたくさんの有益な情報を提供して頂けただけに残念ではありますが、今後も別の形で情報発信を続けられるということなのでその時を楽しみにお待ちしております。また、この場を借りてお礼を申し上げます。

HumanIKは何かと嫌われることの多いツールですが、リギングが苦手な人にとっては非常に簡単にリグコントローラを提供してくれます。
さらに最近ではクイックリグツールによって骨入れからスキニング・そしてリギングまで一瞬で完結できるようになり一層お手軽さが増しました。

また、HumanIKのリターゲット機能は非常に強力です。
モーションキャプチャによるデータをモデルに流し込む使用例が一般的ですが、ゲーム案件ではジョイント名や骨位置・数の違うモデルに対して流し込むのにもとても便利で・・・ｳｯｱﾀﾏｶﾞ

はい、そんなわけでHmumanIKをコマンドで操作できるようになるともっと便利になります！
この記事が何かのお役に立てれば幸いです。

それでは皆様、よいお年を！メリークリスマス！