はじめに
この記事は、3DCG業界で働くArtist向けのMEL入門記事です。
普段の業務を効率化したいけど、MELの書き方が分からない、調べたけどイマイチ分からなかった、そんな方向けに書きました。
本記事は「lsコマンドを使う」をゴールとします。
環境
Autodesk Maya 2022.2
前回のあらすじと今回へのつなぎ
前回は変数を使いました。変数を使えるようになった今では、MELで実行できる幅が格段に広がったのではないでしょうか?
さて、今回はls
コマンドを学んでいきます。変数をふんだんに活用するls
コマンドはMELのなかでもかなり重要なコマンドになります。一つずつしっかりと確認していきましょう。
lsコマンドの概要
ls
というのはListの略です。
リストアップとよく言いますよね。
ls
コマンドの主な挙動としては、「フラグで指定したものを配列型で返す」です。
配列型とはなんぞや?
int, float, stringに続く新しい型になります。
しかし今までの型とは少し毛色が違います。
まずは初期化する場合の文法を見ていきましょう。
型名 $変数名[要素数] = {要素0, 要素1, 要素2、...}
実際のMELだと下記です。
string $cubeNames[3] = {"CubeA", "CubeB", "CubeC"};
配列型は、実直に言ってしまえば、ある型の値を複数個保持できる型です。
上記の変数cubeNames
はstring型の値を三つ保持しています。
保持できる値のことを要素といい、その数を要素数といいます。
配列型を使ってみる
実際に使ってみるのが一番理解がはかどります。
配列型を活用して、CubeA、CubeB、CubeCを生成するMELを書いてみます。
string $cubeNames[3] = {"CubeA", "CubeB", "CubeC"};
polyCube -name $cubeNames[0];
polyCube -name $cubeNames[1];
polyCube -name $cubeNames[2];
まずは実行して確認しましょう。
うまくいきました。
より詳細な文法を見ていきましょう。
配列型の文法
まず、初期化時の文法ですが、
string $cubeNames[3] = {"CubeA", "CubeB", "CubeC"};
上記は当然OKですが、実は、
string $cubeNames[] = {"CubeA", "CubeB", "CubeC"};
こちらの記法でもOKです。変数宣言の要素数を省略できるんですね。
初期化が終わったら、次は使用法です。
配列は一つの変数の中に複数個の値を保持しています。なので実際に-name
フラグ用の値を適用する際には、変数cubeNames
のどの値を使うのかを指定する必要があります。
polyCube -name $cubeNames[0];
指定自体はシンプルで、変数名の後ろに[]
をつけ、[]
内に使いたい要素の順番を書きます。
この要素の順番のことを添字といいます。
上記だと変数names
中の添字が0の要素を使う、ということになります。
一つ注意なのはこの順番は、1からのスタートではなく、0からのスタートだということです。
要素数が3の配列は、添字は、0, 1, 2となります。
1, 2, 3ではないので、十分に気をつけてください。
間話 printコマンド
突然ですが、「変数の中身は今はこれがこうで...」と考えるのって少し大変じゃありませんか?
変数の中身を確認することができれば多少は楽ができそうです。
そして、便利なことにそんなコマンドが存在します。
print()
print
コマンドといいます。
使い方としては、print
コマンドの後ろの()
に変数を入れるだけです。
float $pi = 3.14;
print($pi);
早速実行してみましょう。
print
の結果はログで確認ができます。
3.14と表示されています。
このように変数の中身を見たりして、プログラムが正常かを確認することをデバッグといいます。
とりわけ、print
でデバッグすることをprintデバッグと呼んだりします。
「この書き方で合ってるはずだけど、何故か上手く動かない」というときは、変数の中身をprintで確認してみましょう。
出力されたログをもとに、ミスが見つかるかも知れません。
lsコマンドを使ってみる
便利なprint
を学んだところで、本題のls
コマンドを実際に使ってみましょう。
今回は選択したオブジェクトたちを取得するMELを書いてみます。
string $selectionObjs[] = `ls -selection`;
print($selectionObjs);
ls
コマンドは「フラグで指定したものを配列型で返す」コマンドでしたね。
MELコマンドリファレンスのls
コマンドのフラグから、-selectionフラグの効果を見てみましょう。
選択したオブジェクトがリストアップできそうですね。
実行前に、適当なオブジェクトをシーンに並べましょう。
あとは、それらを選択した状態にしておきます
それでは実行していきましょう。
無事に四つのオブジェクト名がログに表示されています。
MEL実践
せっかくls
コマンドを使用できるようになったので、前回作った、
float $cubeATranslateX = `getAttr "CubeA.translateX"`;
float $cubeATranslateY = `getAttr "CubeA.translateY"`;
float $cubeATranslateZ = `getAttr "CubeA.translateZ"`;
setAttr "CubeB.translateX" $cubeATranslateX;
setAttr "CubeB.translateY" $cubeATranslateY;
setAttr "CubeB.translateZ" $cubeATranslateZ;
このMELをパワーアップしてみましょう。
「パワーアップもなにも、このままでもいいじゃん」を思う方がいるかもしれません。ですがよく考えてみてください。このMELはオブジェクト名が「CubeA」と「CubeB」でしか正常に動作しないのです。
このままでは汎用性がありませんよね。
しかしls
を使えば現在選択しているオブジェクトを取得できるので、少なくとも「CubeA」と「CubeB」でしか動かないなんてことは回避できそうです。
それではまず、MEL作りの計画から始めましょう。
動作要件としては、「一番目に選択したオブジェクトの位置を二番目に選択したオブジェクトの位置に合わせる」でやってみます。
今回はわかりやすさ重視のため、シーン上にはCubeとConeを用意します。
一番目にCube、二番目にConeを選択し、MELを実行すると、Cubeの位置がConeの位置と同じになればOKということにします。
まずは、移動するオブジェクト(一番目に選択したオブジェクト)と、移動先のオブジェクト(二番目に選択したオブジェクト)を取得してみます。
ls
コマンドにおいて、選択した順番と配列に格納される順番の関係性はわかりませんが、一旦選択した順番でオブジェクトが格納されている想定でMELを書いてみましょう。
print
も活用して、配列の中身を見てみます。
string $selectionObjs[] = `ls -selection`;
string $firstSelectionObj = $selectionObjs[0];
string $secondSelectionObj = $selectionObjs[1];
print($firstSelectionObj);
print($secondSelectionObj);
pCube1pCone1
ログを見ると、CubeとConeの名前は取れているようですが、改行されていません。
実は、print
では意図的に改行しない限り改行はされません。
改行を表す\n
を間に挟んで、再度実行してみましょう。
うまくいきましたね。
改行に気を取られていましたが、選択した順番で配列に格納されている予想は当たっていましたね。このまま作業を続けていきましょう。
オブジェクトが取得できているので、後は位置を取得・設定する処理と合体するだけで完成になりますね。
しかしここで一つ問題があります。getAttr
コマンドに「"オブジェクト名.アトリビュート名"」という形式の文字列を渡す必要がありますが、オブジェクト名は現在変数で用意しています。どうすればいいのでしょうか?
float $cubeATranslateX = `getAttr $secondSelectionObj".translateX"`;
間話 文字列の結合
実は文字列は+
を使うことで結合することができます。
string $firstName = "my";
string $secondName = "Cube";
string $combinedName = $firstName + $secondName;
polyCube -name $combinedName;
ちなみに()
で囲いさえすれば、コマンド内でも結合することができます。
string $firstName = "my";
string $secondName = "Cube";
polyCube -name ($firstName + $secondName);
MEL実践(2)
文字列の結合法がわかれば後は書くのみです。
string $selectionObjs[] = `ls -selection`;
string $firstSelectionObj = $selectionObjs[0];
string $secondSelectionObj = $selectionObjs[1];
float $secondTranslateX = `getAttr ($secondSelectionObj + ".translateX")`;
float $secondTranslateY = `getAttr ($secondSelectionObj + ".translateY")`;
float $secondTranslateZ = `getAttr ($secondSelectionObj + ".translateZ")`;
setAttr ($firstSelectionObj + ".translateX") $secondTranslateX;
setAttr ($firstSelectionObj + ".translateY") $secondTranslateY;
setAttr ($firstSelectionObj + ".translateZ") $secondTranslateZ;
一番目にCubeを、二番目にConeを選択して、
実行してみましょう。
やりました!大成功です!
これはかなり実践的なMELが書けたのではないでしょうか?
おわりに
いかがでしたか?配列型にlsコマンドにと大ボリュームでしたね。
新しい要素は読むだけ理解するだけ、ではなく、実際にスクリプトを書いて、体験して覚えるのが上達の近道です。
実際にスクリプトを書くと、本記事では説明していない文法やエラーに当たってしまうこともあるかと思います。そんなときでも一つずつ落ち着いて原因を探し出し、時にはインターネットの情報も駆使して、解決を目指してみてください。
そしてうまくMELが動いたときには存分に達成感に浸ってください!
次回はこちら→【ArtistでもMELが書きたい】Maya MEL入門(9)
参考