【ArtistでもMELが書きたい】Maya MEL入門(6)【setAttrとgetAttr】


# はじめに
この記事は、3DCG業界で働く**Artist向けのMEL入門記事**です。
普段の業務を効率化したいけど、MELの書き方が分からない、調べたけどイマイチ分からなかった、そんな方向けに書きました。
本記事は「setAttrとgetAttrを使う」をゴールとします。

# 環境
Autodesk Maya 2022.2

# 前回のあらすじと今回へのつなぎ
[前回](https://qiita.com/Hum9183/items/d148f2ba3d2b55f70cd6)はスクリプトエディタのヒストリを使い効率的にコマンドを調べました。
コマンドの調べ方も楽になり、ログをコピペするだけでである程度のMELを記述できるようになったわけですが、
最後の方で`setAttr`というコマンドが出てきましたよね。キューブを移動させるコマンドのように思えますが、フラグにつけなければいけない`-`(ハイフン)がついていなかったりと謎が多いです。
`setAttr`は何かと使う機会が多いので、使い方を調べていきましょう。

# setAttrの動作を振り返る
よくわからないコマンドが出てきたときは、とにかく[コマンドリファレンス](https://help.autodesk.com/view/MAYAUL/2022/JPN/index.html?contextId=COMMANDS-INDEX)を参照しましょう、といいたいところですが、`setAttr`は少し特殊なため、前回のMELを参考に見ていきましょう(コメントや余計なフラグは取り除いています)
```
polyCube;
setAttr "pCube1.translateX" 1;
```
現時点では文法に関しては謎だらけです。
```
setAttr "謎1.謎2" 謎3
```
とりあえず、振り返りがてら実行します。
![MEL_learning01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3121056/ef7eeab6-0cec-1045-0464-755ab1b1ec49.png)
![MEL_learning02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3121056/21ce516f-9bc0-28a4-fd0d-4ef8ec7086ac.png)
![MEL_learning03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3121056/2a8242cd-93f7-c29b-50ce-e3e8b5028d7f.png)
キューブが生成されて、「移動X」が1に設定されています。

ここからは色々とMELを書き換えて実験していきます。
MELを書き換えて、結果がどう変化したかを観察することで文法を探っていきます。

# setAttrの文法を探る(1)
現時点で判明している文法は以下です。
```
setAttr "謎1.謎2" 謎3
```
`謎3`に関しては、なんとなく`移動させる値`なのかなという予想がつくかと思います。
その予想が本当なのか、実験してみましょう。

試しに、`謎3`の部分が**1**となっている部分を**3**にしてどう変化するか見てみます。
```
polyCube;
setAttr "pCube1.translateX" 3;
```
![MEL_learning04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3121056/2a36e660-9c1b-ffc8-37a0-b011b1c0bc6a.png)
![MEL_learning05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3121056/ff380673-c677-d02d-05b8-5709288dfbdb.png)
![MEL_learning06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3121056/f020a12a-0b68-d7a9-0ba9-9cba41689c4b.png)
キューブの「移動X」が3になりましたね。
予想は正しかったわけです。

文法的には、
```
setAttr "謎1.謎2" 設定する値
```
こんな感じでしょうか？

# setAttrの文法を探る(2)
`"謎1.謎2"`は`"pCube1.translateX"`となっています。

`pCube1`というのは、キューブを生成した際につけられるデフォルトの名前です。
シーンに何もない状態で`polyCube`を実行すると、生成されるキューブの名前は`pCube1`になるかと思います。
もしかしたら`謎1`は`移動させるオブジェクトの名前`なのかもしれません。
早速検証してみましょう。

```
polyCube -name henohenomoheji;
setAttr "henohenomoheji.translateX" 3;
```
名前が「henohenomoheji」のキューブを生成し、
そのキューブの「移動X」を3に設定するMELです。
これで試してみましょう。
![MEL_learning10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3121056/17a6fdb1-f599-3098-6593-6e3db55060cf.png)
![MEL_learning12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3121056/7f2f82de-0038-13b5-9e90-242949578d29.png)
![MEL_learning11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3121056/95c46879-0ba8-338a-020c-abad57a5f359.png)
うまくいきました！

文法的には、
```
setAttr "オブジェクト名.謎2" 設定する値
```
こういうことですね。

# 間話 アトリビュート
`謎2`に取り掛かる前に、一つMayaのアトリビュートについて見ていきます。

https://knowledge.autodesk.com/ja/support/maya/learn-explore/caas/CloudHelp/cloudhelp/2016/JPN/Maya/files/GUID-D53B9E3D-E6E3-4CC3-A38F-3AA3A09205E5-htm.html

アトリビュートとは簡単にいうと、**オブジェクトが保持できる値**[^1]のことです。
具体例をあげると、pCube1オブジェクトは「移動X」と「移動Y」、「移動Z」といったアトリビュートを持っている、という感じです。

チャネルボックスでは可視化されていますね。
![MEL_learning13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3121056/9992217f-1caf-8fb3-c272-1e45bed2c4d7.png)
当然ですが、チャネルボックスで移動Xに5と入力すると、pCube1のX座標は5になります。
アトリビュートはその**オブジェクトの状態を表現している**わけなんですね。

ちなみにですが、アトリビュートは英語で書くと**Attribute**です。
Attribute...どこかでみたことがありますね。
Attr...そう、`setAttr`です！

もしかすると、`setAttr`はアトリビュートに値を設定するコマンドなのかもしれません。

# setAttrの文法を探る(3)
現在明らかになっている文法は、
```
setAttr "オブジェクト名.謎2" 設定する値
```
です。
もし仮に、`setAttr`はアトリビュートに値を設定するコマンドなのだとしたら、
`謎2`は**アトリビュート名**なのかもしれません。
値を設定する際に、アトリビュートの名前を指定しないのは不自然です。

となると、アトリビュート名を知りたいです。
これまでMELを書いてきて感じる傾向として、日本語は受け付けてくれませんよね？(コメントを除く)
ですので「移動X」というアトリビュート名では、良くないことは予想できるかと思います。

# ノードエディタで英語のアトリビュート名を知る
幸いにも、簡単に英語のアトリビュート名を知る方法があります。
シーン上のキューブの「移動X」アトリビュートの英語名の発見を目標にしてみます。

まずは、ウィンドウ→ノードエディタでノードエディタウィンドウを開きましょう。
![MEL_learning14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3121056/6ff7d946-54af-725e-2b21-d3d5eb982948.png)
![MEL_learning15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3121056/1cd0398a-7f9e-721c-cf8f-ddc26401adbc.png)
キューブを選択した状態で、下図のアイコンを押すと、**ノード**が表示されます。
![MEL_learning16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3121056/217001e7-76f8-f301-cdca-229e38b494a7.png)
![MEL_learning17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3121056/f769f1ba-d5e1-5190-fd82-0cb3c123d970.png)
デフォルト状態ではアトリビュートたちは隠されています。ノードのハンバーガーボタンをクリックして展開していきます。
![MEL_learning18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3121056/08f86964-7b0f-e198-c7da-38e1c1aa3727.png)
移動アトリビュートは更に詳細が隠されています。こちらもクリックで展開します。
![MEL_learning23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3121056/8b2608da-ea66-2944-67be-45ef6f982d72.png)
![MEL_learning19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3121056/5f33a384-1a40-4894-0dbf-4437553d16cb.png)
「移動X」を発見しました。

緑の丸ちょぼにマウスカーソルを合わせるとポップアップが出てきます。
![MEL_learning20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3121056/18f921f5-3a91-6fac-51ff-8188461d822a.png)
```
translateX Type: doubleLinear Value: 3
```
`translateX`というのがまさにアトリビュート名になります。
`Type: doubleLinear`は型というものです。現状は無視して構いません。
`Value: 3`は値が3ということです。先程のMELで「移動X」を3に設定したので、それがそのままになっているようですね。

あれ、`translateX`というと、今実験しているMELと全く同じテキストですね、
...これはもう正解な気がしますが、念のために最後の確認と行きましょう。

# setAttrの文法を探る(完)
現在明らかになっている文法は、
```
setAttr "オブジェクト名.謎2" 設定する値
```
です。

`謎2`の箇所に`translateX`を当てはめると以下のようになります。
```
polyCube;
setAttr "pCube1.translateX" 1;
```
動く可能性は非常に高いと思いますが、念のため実行します。
![MEL_learning21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3121056/725e0bcf-95a6-cc8c-331b-9871d918ce4a.png)
![MEL_learning22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3121056/aefedb14-0617-30cb-aeaa-e7c436af7bbd.png)
大丈夫でしたね。

せっかくなので、試しにほかのアトリビュートも試してみましょう。
「回転Y」なんてどうでしょうか？
![MEL_learning24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3121056/cc6cee68-23f7-4c5f-2ab0-f0cada394576.png)
```
rotateY
```
```
polyCube;
setAttr "pCube1.rotateY" 30;
```
![MEL_learning25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3121056/07885971-0e36-90ac-78a4-5f78c91b3704.png)
実行してみます。
![MEL_learning26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3121056/fd9deb63-9772-348e-32de-136b1f242432.png)
![MEL_learning27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3121056/d4587764-192c-3da1-ed37-ba2a47c28726.png)
大成功です！

最終的なsetAttrの文法はこうなりますね。
```
setAttr "オブジェクト名.アトリビュート名" アトリビュートに設定する値
```

せっかく明らかになったところ言い出しにくのですが、`setAttr`はフラグを使うこともできるため、文法はこの限りではありません。
しかし、アトリビュートに値を設定するMELであれば、上記の書き方で概ねカバーできると思います。

# getAttrを知る
`setAttr`で大ボリュームだったかと思うのですが、
`setAttr`と対をなす`getAttr`も合わせて覚えておくと大変便利です。

`setAttr`はアトリビュートに値を設定するコマンドなのに対し、
`getAttr`はアトリビュートの値を取得するコマンドです。

文法は以下です。
```
getAttr "オブジェクト名.アトリビュート名"
```
値を取得するコマンドなので、設定する値がありません。スッキリしていますね。
実際のMELだと下記のような感じでしょうか。
```
getAttr "pCube1.rotateY";
```

# getAttrを使う
試しに、回転値が入ったキューブが存在するシーンで、
![MEL_learning28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3121056/faac0139-5cd8-114c-ce9e-7bca2ee09584.png)
「回転Y」の値を取得してみましょう。
![MEL_learning29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3121056/fc6c7f58-f197-b27d-eff9-ceef5bec75c5.png)
実行結果は、スクリプトエディタのヒストリに表示されます。
![MEL_learning30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3121056/adef379d-59b4-d58a-46eb-b5de23afaa70.png)
```
// 結果: 30 // 
```
うまくいきましたね。「回転Y」は30だという情報を取得できています。

# おわりに
いかがでしたか？
アトリビュートを操作することはMELでスクリプトを書く上で非常に大切になってきます。
今回は「移動」や「回転」など基本的なアトリビュートを設定・取得しましたが、Mayaの便利な内部設定としてアトリビュートは数多くのものが実装されています。
ノードエディタを見たり、有志のMELを読んでみると、知らなかったアトリビュートが発見できるかも知れません。

次回はこちら→[【ArtistでもMELが書きたい】Maya MEL入門(7)](https://qiita.com/Hum9183/items/acd66f3275f87f7295d9)

[^1]: 正確な言い回しは異なりますが、本件を解決するためには、ざっくりとその認識でも問題ありません。正確な定義を知りたい方はAutodesk公式のドキュメントをご参照ください。