Maya標準機能のRunTimeCommandの内容を探す

## TLDL
1. Hotkey Editor から探しましょう。  
(Easy)
2. 大体は ```defaultRunTimeCommands.mel```  にあるので頑張って見つけましょう！  
(Normal)
3. ```runTimeCommand -q -c command_name``` と ```whatIs procedure_name```を併用して頑張りましょう。  
(Normal+)

## はじめに
はじめまして、赤城 巧です。
普段はゲーム開発会社でパイプライン系TAもどき[^1]をやっております。

[^1]: 弊社内では特にパイプラインやR&Dなどの分類はないため「もどき」としている。


皆さまは **[whatIs](http://help.autodesk.com/cloudhelp/2019/ENU/Maya-Tech-Docs/Commands/whatIs.html)** コマンド使っていますでしょうか？
私は、日々 ~~嫌々~~ 活用しております！！

まずは初学者向けに whatIs コマンドについて話しますので、
既に知っている方は **[こちらへどうぞ！](#でランタイムコマンドはいずこに)**

## whatIsコマンドについて

定義されたオブジェクトの型を知りたいときに使います。
また、ファイルを読んで定義されたMELプロシージャの場合はファイルを渡してくれます。

私はScriptEditorに出た内容をとりあえずぶち込む感じで使いますね。

### 利用例

1. 「ある操作をシェルフボタン1つで実行したい」と相談が来る。

2. Maya の ScriptEditor を開き、
   **「Echo all commands / すべてのコマンドのエコー」**を有効にして、
    実行履歴を全て表示するモードに切り替える。

3. 手順1の操作を行い、履歴から該当するコマンドを特定する。
   * ScriptJobでフックされて実行されたコマンドも大量に乗るけど**頑張る**。負けない。
 
4. コマンドを特定できたら、以下をMELコマンドラインに入力する
    * ```whatIs command_name```

5. 以下の結果が帰ってくる。
結果は大きく分けて3種類に分類される。
   * **Result: Command**
     * **通常のMELコマンドです。**
     * 大体は、そのまま切り出せば問題ありません。  
       あとはドキュメントとにらめっこして、テキトーに頑張ろー！
   *  **Result: Mel procedure found in: .../hoge/fuga.mel**
      *  **Melプロシージャとして定義されています。**
      *  Melとしてそのまま実行するなり、  
         Python から maya.mel.eval() なりしてくださいな。
         *  自分は機能を切り出す前には、  
            必ず元のスクリプトファイルを読むようにしています。
            (想定外の使い方をしたり、変な副作用があると不味いので...)
   *  **Result: Run TimeCommand**
      * **ランタイムコマンドとして定義されています。**
      * Mayaの標準機能の多くは、Defaultフラグが付いたランタイムコマンドとして登録されています。  
      * **今回の記事は、この返り値に定義元のファイルパスがない、ランタイムコマンドの内容を追う話です。**

6. 他、様々なことを検討し、必要があれば実装して提供する。

## ランタイムコマンドってなに？

そもそもランタイムコマンドってなんでしょう？

[ランタイム コマンドを作成する | Maya 2016 | Autodesk Knowledge Network](https://knowledge.autodesk.com/ja/support/maya/learn-explore/caas/CloudHelp/cloudhelp/2016/JPN/Maya/files/GUID-2B2BE446-D622-4274-80FC-2A5EF7D87C5C-htm.html)

> ランタイム コマンドは、MEL コマンド、Maya コマンド、MEL プロシージャなどの他のコマンドやスクリプトで構成されるコマンドです。
> ランタイム コマンドは、短いラベルを使用して MEL コマンドラインで長いスクリプト(またはスクリプトの設定)を実行できる「一語のラッパー」 またはエイリアスと考えられます。
> 実行可能な多くのメニュー項目とアイコン(すべてではない)で、起動にランタイム コマンドを使用しています。

なるほど。大体わかった。
つまりプロシージャをまとめて、MELコマンドとして扱える機能です。

例えば、こんな感じで使えます。

```python
from maya import cmds
from maya import mel

_script = 'print "Hello RunTimeCommand!"'
title = 'MyHelloCommand'

print(hasattr(cmds, title))
# Result: False # 

# ランタイムコマンドを作成
cmds.runTimeCommand(title, ann="Print World", c=_script)

print(hasattr(cmds, title))
# Result: True # 

cmds.MyHelloCommand()
# Hello RunTimeCommand

mel.eval('whatIs %s' % title)
# // Result: Run Time Command // 
# Result: u'Run Time Command' # 
```

無事、作れましたね！
このコマンドは Maya終了時に Prefs/userRuntimeCommands.mel に保存されます。

```userRuntimeCommands.mel
runTimeCommand
	-annotation "Print World"
	-category ""
	-hotkeyCtx ""
	-commandLanguage "python"
	-command ("print \"Hello RunTimeCommand!\"")
	MyHelloCommand;
```

起動時には読まれるので、次回以降はは宣言しなくても使えるわけです！

> TIPS: 保存したくない場合はdefaultオプションをTrueにしてコマンドを作成します。
> 
> ツールとして提供する場合、起動スクリプトを実行しているプロジェクトであれば、
> 毎回起動時に宣言したほうが、長期的に見て管理しやすいかもしれません。

### で、ランタイムコマンドはいずこに

実はruntimeCommandで作成したコマンドの内容は
```runtimeCommand -q  -c (コマンド)```で読めます。


```
whatIs CreateReference;
// Result: Run Time Command // 

runTimeCommand -q -c CreateReference;
// Result: preCheckColorManagement(); projectViewer Reference; checkColorManagementMissingColorSpaces(); // 


whatIs preCheckColorManagement;
// Result: Mel procedure found in: C:/Program Files/Autodesk/Maya2018/scripts/startup/colorManagementUtilities.mel // 

whatIs projectViewer;
// Result: Mel procedure found in: C:/Program Files/Autodesk/Maya2018/scripts/others/projectViewer.mel // 

whatIs checkColorManagementMissingColorSpaces;
// Result: Mel procedure found in: C:/Program Files/Autodesk/Maya2018/scripts/startup/colorManagementUtilities.mel // 
```

…複数行を纏めてる場合もあるのか…

## 別解

最近になって、Program Files下にあるMayaのScriptsフォルダを漁っていて見つけました。

```C:\Program Files\Autodesk\MayaXXXX\scripts\startup\defaultRunTimeCommands.mel```

startupフォルダ以下にあるスクリプトはスタートアップ時に読み込まれます。
このファイルは名の通り、Defaultフラグの付いているランタイムコマンドを作成しているようです。

このスクリプトファイルからコマンドを登録している部分を探し、
登録されたコマンドを```whatIs```すれば、お目当ての部分に到達するはずです。

ちなみにこのMELファイル、Maya2018で1万8000行近くあるので、
Ctrl+Fなり、文明の力をちゃんと利用して探しましょう。


個人的にはVSCodeでScriptsフォルダを開いてから作業すると、
引っかかったコマンドを検索すれば、処理が追いやすいので便利です。


## その後。

と色々書き並べていましたが、  

実はGoogle検索で「whatIs Maya RuntimeCommand」以下のページで出ます！  

[実行しているMELコマンドの詳細を調べるには? | Maya 2018 | Autodesk Knowledge Network](https://knowledge.autodesk.com/ja/support/maya/troubleshooting/caas/sfdcarticles/sfdcarticles/kA230000000u0Uc.html)


また、別のトラブルシューティングにもかいてあります！！！:zap::zap: 

[MELスクリプトの処理を調べたい | Maya | Autodesk Knowledge Network](https://knowledge.autodesk.com/ja/support/maya/troubleshooting/caas/sfdcarticles/sfdcarticles/kA230000000u0Uc.html)

(この記事の意義とはいったい……うごごご！)


**みんなはドキュメントもちゃんと読もうね！！！！**

(正直、トラブルシューティングまで追ってらんないッス……
 せめて開発者向けドキュメントに書いてほしいな……Mayaさま……)


## 終わりに

実は月曜早朝に「もう1本記事ができたぜー」なんてルンルン気分で書き上げたのですが、
そのときは、何故か defaultRuntimeCommand の内容が コマンドから照会できないと思い込んでいて、
defaultRunTimeCommands.mel を紹介して、そこから処理の中身を切り出そう！という内容でした。

当初はランタイムコマンドについての解説もなく、
木曜に大急ぎで修正、追記したので記事の流れも若干よく分からなくなってしまいました。

こうやって記事として纏めていると、間違った知識も修正されて良いですね！(開き直り)

まだまだ[2019年のMaya Advent Calendar](https://qiita.com/advent-calendar/2019/maya)には枠がありますので、
みんなも記事を書いて、知識をより確かなものにしよう！！！


以上、飛び込み記事でした！オサラバ！