見出し画像

MayaのMELを使おう!基礎編第5回~プロシージャ~

こんにちは!G2 Studiosで3Dアニメーターをやっている嶽本(タケモト)です!
MayaのMELの基礎講座第5回です。
前回、最終回…と書きましたが(笑)、大切な要素を思い出しましたので、第5回として「プロシージャ」についてお伝えします。

▼これまでの連載はこちら
第1回~作業準備~
第2回~コマンド入力と四則演算~
第3回~変数と配列~
第4回~if文・比較演算子・論理演算子・for文~


プロシージャとは

プロシージャは、日本語で「手続き」、他の言語では「サブルーチン」だったり、Office系のソフト等では「関数」と呼ばれることもあります。
これは任意の処理をひとまとめにして使えるようにしたもので、ひらたく言えば、球を作って複製して移動して~のような複数の処理をまとめてひとつの命令文で処理を呼び出せるようにするものです。


なにができるの?

例えばこのようなスクリプトがあるとします。

処理a
処理b
処理c
処理d
処理e
処理a
処理b
処理c
処理f

長くて大変そうですね…。
しかしよく見ると処理abcの順に並んだ部分が2回出てきています。これをまとめてしまいましょう。
「処理abc=プロシージャA」とします。

処理abc=プロシージャA とする

プロシージャA
処理d
処理e
プロシージャA
処理f

すっきりしました。


ここでは数行しか減っていないように見えますが、実際は処理のひとつひとつが数十行、数百行になることも多いのでずいぶん楽になります。
長いスクリプトを書く際にタイピングする文字数や行数が劇的に減り、修正する時も一か所で済むために修正漏れ等も防げます。

また、ボタン等に複雑な処理を仕込む場合にも有用です。


以下、例を挙げます。
まずはウィンドウを作成し、球が生成されるボタンを配置してみましょう。

window;
 columnLayout;
  button -command "polySphere;";
showWindow;

「polySphere」コマンドはポリゴン球を生成するコマンドで、何も指定しなければ保存されている設定がそのまま適用されます。
このままでは環境によって作られるものが違ってしまうので、半径や分割数、オブジェクト名をフラグで指定してみます。

window;
 columnLayout;
  button -command "polySphere -radius 10 -subdivisionsAxis 10 -subdivisionsHeight 12 -name testPolySphere;";
showWindow;

横幅が窮屈になってきました。
さらにボタン一回でキューブとシリンダーも生成されるようにしてみます。

window;
 columnLayout;
  button -command "polySphere -radius 10 -subdivisionsAxis 10 -subdivisionsHeight 12 -name testPolySphere;polyCube -depth 5 -height 7 -width 2 -name testPolyCube;polyCylinder -height 12 -radius 5 -name testPolyCylinder;";
showWindow;

非常に見づらいですね。通常、コマンドはフラグ毎に改行しても問題なく動作しますが、3行目の""で囲われた部分は改行できません。
””の部分は文字列として認識されるのですが、スクリプト内で文字列を改行することには対応できないためです。
そのため、ボタンに複数の処理を仕込もうとするとどんどん横に伸びて見づらいものになってしまいます。

そこで、これをさきほどのようにプロシージャにまとめてしまえば…

global proc testProc(){
 polySphere -radius 10 -subdivisionsAxis 10 -subdivisionsHeight 12 -name testPolySphere;
 polyCube -depth 5 -height 7 -width 2 -name testPolyCube;
 polyCylinder -height 12 -radius 5 -name testPolyCylinder;
}

window;
 columnLayout;
  button -command testProc;
showWindow;

このようにできます。1~5行目がプロシージャを定義し、9行目で使用しました。
ずいぶん見やすくなったので、ボタンの処理内容を変更修正するにも理解しやすいかと思います。


書き方

プロシージャの書き方はこうです。

①global proc プロシージャ名(変数){処理内容}
②global proc 変数型 プロシージャ名(変数){処理内容}

①が処理をするだけの場合で、②は処理の結果を得たい場合の書き方です。

「global proc」はグローバルプロシージャであることを示しています。(ローカルについては後述)
「変数型」は、処理の結果から値(返り値)を得たい場合に指定します。得たい結果に合わせて設定してください。
「プロシージャ名」には任意の文字列を指定してください。他の場所でこれをコマンド名のように使います。
「変数」は省略可能です。処理内容に変化を加えたい場合はここで変数を作り、値を変更できるようにしておきます。
「処理内容」には処理内容を書きます。

ここから具体的な例を書いていきます。


まずはシンプルな書き方。

global proc testP(){
 print "testPプロシージャを実行した";
}
testP;
testP;
testP;

//結果:testPプロシージャを実行したtestPプロシージャを実行したtestPプロシージャを実行した

適当な文字列を表示するtestPプロシージャを作成し、4~6行目で3回実行しました。
プロシージャ名をコマンドと同じように使えているのがわかると思います。

次に変数を使ってみます。

global proc testP(string $hensu){
 print ($hensu + "回目");
}
testP(1);
testP(2);
testP(3);

//結果:1回目2回目3回目

どうでしょうか。
testPプロシージャの変数の部分を設定したので、4~6行目で()内に入れた文字が
処理内容に反映され、それぞれ別の結果が出力されました。

変数は複数設定してもOKです。以下、例です。

global proc testP(int $hensu1,string $hensu2){
 print ($hensu1 + $hensu2);
}
testP(1,"回目かな");
testP(2,"回目かも");
testP(3,"回目かよ");

//結果:1回目かな2回目かも3回目かよ

次は、返り値を得る書き方です。

global proc string testP(){
 string $temp = `date`;
 return $temp;
}
testP;

//結果:現在の日付&時刻

「date」は現在の日付や時刻を得るコマンドです。
処理の中で得た値を、testPプロシージャを実行した時に返すようになっています。

最後に変数と返り値を両方使った書き方。

global proc int testP(int $temp){
 return $temp * $temp;
}
testP(5);

//結果:25

変数に入れた数字の二乗を返すようにしてみました。

このように、プロシージャを理解すると新しいコマンドを作るようなことが可能になります。
MELに慣れてきて複雑な処理を行うようになってきたら、プロシージャを使って整理できないか考えたり、いっそ使う前提で全体を設計できるようになると思います。

そうなったらもう初心者は卒業と言っていいでしょう!

▼これまでの連載はこちら
第1回~作業準備~
第2回~コマンド入力と四則演算~
第3回~変数と配列~
第4回~if文・比較演算子・論理演算子・for文~

▼G2 Studiosとは…


X(Twitter)にて最新のお知らせを配信しております。ぜひフォローしてください!