チュートリアル / 読んで触ってよくわかる!Mayaを使いこなす為のAtoZ
第41回:スクリプトを配布するためのMELの作法(1/2)
- Maya
- ゲーム
- コラム
- スクリプト・API
- チュートリアル
- 中級者
- 学生・初心者
- 教育
- 映画・TV
MELでツールを作るのに皆さんどのように作りますか?いきなり「myTool.mel」というふうにmelファイルを用意して作るよりも、スクリプトエディタで機能をちょっとずつ実行しながら作っていくことが多いと思います。特に規模の小さなスクリプトはそうするのではないでしょうか。
とある背景制作のアーティストが自給自足でツールを作ったとします。別の背景制作班のアーティストに作ったツールの話をしていると、同じ分野の仕事なら同じような所で悩んでいるものでして、そのアーティストが「ツール使いたい!」となるのも自然なことです。はたしてどうやって渡すべきか、なかなか悩ましいところです。
メッセンジャーやメールでスクリプトを送るというのはよくある方法です。シェルフに登録してあるスクリプトや、スクリプトエディタに書いたままにしているスクリプトをメールにコピペして送ります。ローテクな感じがしますが、実は確実にスクリプトを他のマシンで動作させられる、意外といい方法なのです。なんだか秘密のやり取りという感じもまたMayaカスタマイズ心をくすぐります:-)
こんな感じで(↓)メールを送ります。
もう、すでにアレな感じがしないでもないですが…。
そうしてツールのやり取りをしていると、段々と面倒なことが起きてきます。ツールを更新するたびに、メールでスクリプトを送らなければいけません。複数ツールがある場合はなおのこと面倒になってきます。さらに送られる方も結構なもので、大量のメールからスクリプトの部分だけ抜き出して、適切なところへコピペしないといけないわけですから、そのうち更新するのが面倒になって、3ヶ月もすれば迷惑メール扱いでフィルタリングして、未来永劫ツールを更新しなくなります。なんということを。
というわけでツールを共有するにはおのずとmelファイルでの受け渡しが必要になってきます。melファイルなら受け取ってそのまま上書きするだけなので、大量にあってもラクラクです。ところがこのmelファイルにはいくつかのルールがあります。スクリプトエディタでMELを実行するのとはちょっと作法が異なるのです。
キーワードは「global proc」「proc」「melファイル名」の関係にあります。いまさらglobal procをなるべく使わないように、とは言いません。むしろglobal procの無難で一般的な使い所をしっかり紹介します。そのほうが実際に役に立つ情報ですし。
melファイルを利用するルールを見つつ、前回作ったポリゴンカウントのツールを配布可能なmelに仕上げましょう!
global proc関数名とmelファイル名は同じにする!
前回作ったツールはポリゴン数をリストアップするツールです。名は体を表すというわけでmelファイル名は
「listNumberOfPolygon.mel」にしたいのです。(小文字始まり、単語ごとに大文字、始めの単語は動詞の名前が基本。Ofが無いほうが見た目は良いですが…。)
となるとおのずとglobal proc名も「listNumberOfPolygon」になります。
前回のスクリプトを見ていただくとお分かりの通り、ツールのスクリプトではいくつかの関数があります。さてどの関数を変更するかというと、一番始めに外部から呼び出される関数をグローバル関数にします。GUIを作って利用するツールでは、普通GUIの起動が一番初めですから、
を
に変更します。
Mayaで関数を実行するとどういう段取り関数が実行されるのでしょうか?例えばMaya内で「listNumberOfPolygon();」と実行すると、まず関数が既にメモリに読み込まれて実行できる状態かどうかチェックします。メモリに読み込まれる?別の言い方をすると、Mayaが認識している状態かどうかとも言えます。実行する関数の中身(関数の定義)が全てメモリに読み込まれていないと、Mayaは関数を認識できないので実行できません。
関数がメモリに見つからない場合「同名のmelファイル」を探します。見つかったらその中の「同名に関数」を実行してメモリに読み込みます。その時「global proc」でなければmelファイル外からアクセス出来ませんから「proc」ではなく「global proc」にしているわけです。
ヘルプドキュメントでは次の場所に説明があります。
「ユーザ ガイド > スクリプティング > MEL とエクスプレッション > 操作方法 > プロシージャをコールする」
ファイル外からアクセス出来るのはglobal proc(グローバル関数)だけ
ファイル外からアクセスできる関数はグローバル関数だけです。proc(ローカル関数)はファイル内でのみアクセスできます。
こんなテストをしてみましょう。
例えばスクリプトフォルダにglobalProcTest.melというファイルがあるとします。内容はこんな感じで、関数を呼ぶとメッセージが表示されるようになっています。
{
print "This is localProc\n";
}
global proc notFileNameButGlobalProc()
{
print "This is notFileNameButGlobalProc\n";
}
global proc globalProcTest()
{
print "This is globalProcTest\n";
}
スクリプトエディタで次のスクリプトを一行ずつ実行します。
notFileNameButGlobalProc(); // global proc
globalProcTest(); // global proc
結果はこんな感じになります。
「globalProcTest()」を実行するまで、globalProcTest.melが実行されないので、上の二つの関数は見つからないとエラーが出ます。
二巡目、もう一度上のスクリプトを実行すると結果が変わります。
「localProc()」のみ見つからないとエラーが出ます。
(ちなみにスクリプトエディタで文字が水色になっているところは、Mayaが認識している関数という事です。「globalProcTest()」を実行すると図のように水色表示になります。)
さて、同じスクリプトを実行したのに、一度目と二度目で結果が異なります。これはなぜでしょうか?Mayaは知らない関数が呼ばれた時、同名のmelファイルを探し、その中の同名のグローバル関数を実行します。それ以外のグローバル関数に関してMayaは「知らない」のです。というわけで一度目はファイル名と同名の関数のみ正しく実行されます。
ファイル名と同名のグローバル関数を実行すると、Mayaはファイル内の全てのグローバル関数をアクセス可能にします。次回以降ファイル内の全てのグローバル関数が利用できるようになります。それで二度目に実行した時に結果が変わったのです。
ローカル関数に関しては依然ファイル外からはアクセスできませんので、二度実行しても「localProc()」はエラーになります。ファイル内ではアクセスできるので、
{
localProc();
}
とするのはOKです。「localProc()」が実行されます。
この挙動を利用した例を紹介します。簡単な計算をいろいろやってくれる便利MEL集を作ったとします、ファイル名は
「mathUtil.mel」とします。中身はこんな感じで。(全然役に立たないMEL集ですが…)
{
return $v1 + $v2;
}
global proc float mathUtil.average( float $values[] )
{
float $result;
for ( $v in $values ){
$result += $v;
}
$result /= size($values);
return $result;
}
global proc mathUtil()
{
print "Load mathUtil\n";
}
実行する時はまずファイル名と同じ関数を呼び出します。
この関数自体は特に何もすることはありません。単にMayaがmelファイルを読み込めるようにするためにあるだけです。その後はファイル内の他のグローバル関数も使えるようになります。つまりこのグローバル関数を呼ぶことでmelファイルを「インポートする」という感じになります。あとは次のように実行します。
// Result: 3 //
mathUtil.average({10,25,50});
// Result: 28.333333 //
このようにきちんとグローバル関数とローカル関数を管理しないと、意図したように動作しないわけです。スクリプトをmelファイルにするとツールが動かなくなったりする原因がここにあります。グローバル関数の仕組みを理解するのはなかなか厄介です。
スクリプトエディタで関数を作って実行している時は、全ての関数がMayaに認識されます。「proc」でも「global proc」でもどちらも実行結果は同じで、ローカル関数もグローバル関数も実質的に同じ、グローバル関数としてふるまいます。
まとめ
今回はmelファイルでスクリプトをやり取りする必要性、グローバル関数名とmelファイル名の関わりを見てきました。あまり図がなくて見た目が楽しくないので、余計なイラストを足したりしていますが、ここらへんで一旦休憩。
次回はローカル関数の使い所と、グローバル関数を使わなければならないところ、他もろもろこぼればなしでツール制作を完了したいと思います。