デザイナーが始めるプログラミング入門 mel編 その2
3DCGデザイナーのオザキです。 前回の「デザイナーが始めるプログラミング入門 mel編 その1」では、プログラミングの基本となるコマンドとフラグと実行ファイルの解説をしました。今回はその続きです。
変数
前回では、作成したコマンドをシェルフを押した時に実行して、立方体を作成するようにしました。しかし、実行する度に同じ立方体しか作成されません。今回は、立方体を作成する時にサイズを変更するようにしてみます。
いつも同じ立方体しか作成出来ないという事は、この時のサイズは固定されている定数です。それに対して、サイズ違いの立方体を作成するので、サイズは変動をする変数になります。中学の時に習うy=axのyとかxです。
この時のyとかxは数字だけでしたが、プログラミングでは数字以外に文字列だとかその他を扱い、その違いを明確にする必要があります。
例えば、0と1は数字です。また、デジタルでいうオンとオフにも当たります。0と1を数字として扱うと足し算や引き算のような演算が出来ますが、文字列として扱うと演算は出来なくなります。このようにして、変数を種類を明確にしておかないと、変数の処理をする時のエラーの原因となります。
変数の種類と宣言
編集の種類は厳密には、変数のデータの型と言います。この変数のデータの型は
整数 / int:小数点がない数字です。
浮動小数点数 / float:小数点がある数字です。
文字列 / string
ベクトル / vector:3つの数字の組の事です。3DCGなので、x座標・y座標・z座標やRGBの三色の組み合わせに使います。
行列 / matrix:少し難しい話になるので、説明は保留にしておきます。
があります。
数字が整数と浮動小数点数とで分かれているのは、処理に大きく違いがあるからです。小数点数が不要な場合、例えば個数だとかは整数にしておきます。
変数のデータの型を決める事を変数を宣言するといいます。変数の宣言の仕方は、データの型を書いて、変数名(yとかxのように)を書きます。そしてmelの場合は特に、変数名の先頭に必ず$を書いておきます。
(mel以外のプログラミング言語では、変数名の先頭に何かを必ず書いておくような決まりはありません。しかし、他の人のコードを見る場合、それがコマンドなのか変数なのかよく分からない事があるので、変数名の先頭に記号を入れておくことは、それが変数だと分かり易くなると個人的には思っています)。また、$の後には数字を使う事が出来ません(maya上でノード名を入力した時に、先頭に数字を入力する事が出来ないとの同じです。)
具体的な変数の宣言の仕方は
int $pCubeSizeW;
です。これは整数で立方体の幅の変数の宣言をしています。
前回、立方体を作るコマンドを
polyCube -w 1 -h 1 -d 1 -sx 1 -sy 1 -sz 1 -ax 0 1 0 -cuv 4 -ch 1;
と書きました。これを変数に置き換えると
polyCube -w $pCubeSizeW -h 1 -d 1 -sx 1 -sy 1 -sz 1 -ax 0 1 0 -cuv 4 -ch 1;
となります。立方体を作るコマンドであるpolyCubeの引数で幅のサイズを指定しているのが-wです。この引数の定数が1だったのを変数の$pCubeSizeWにしました。このコマンドを実行すると、幅が任意のサイズで高さと奥行きが1のサイズの立方体(直方体)が作成されます。
立方体の幅の変数を$pCubeSizeWとしましたが、立方体の幅の引数である-wにしか使えない訳ではありません。
polyCube -w $pCubeSizeW -h $pCubeSizeW -d $pCubeSizeW -sx 1 -sy 1 -sz 1 -ax 0 1 0 -cuv 4 -ch 1;
と書くと、幅と高さと奥行きが同じ値の任意のサイズの立方体が作成されます。
変数の代入
上記のコマンドの例を実行すると「任意のサイズの立方体が作成されます。」と書きましたが、「任意のサイズ」ではコンピュータが困ります。エラーの原因になります。なので、変数の初期値を決めておきます。この変数の値を決める事を代入と言います。具体的な変数の代入の仕方は
$pCubeSizeW = 1;
です。これで変数$pCubeSizeWの値が1と決まったので
int $pCubeSizeW;
$pCubeSizeW = 1;
polyCube -w $pCubeSizeW -h 1 -d 1 -sx 1 -sy 1 -sz 1 -ax 0 1 0 -cuv 4 -ch 1;
を実行すると、幅・高さ・奥行きのサイズが1の立方体が作成されました。
int $pCubeSizeW;
$pCubeSizeW = 2;
polyCube -w $pCubeSizeW -h $pCubeSizeW -d $pCubeSizeW -sx 1 -sy 1 -sz 1 -ax 0 1 0 -cuv 4 -ch 1;
を実行すると、幅・高さ・奥行きのサイズが2の立方体が作成されます。
数学ですと = は左右で等しいという意味になりますが、プログラミングでは右の値を左に代入するという意味になります(等しいを意味する記号は後述します)。
上記では、変数の宣言と代入を別々にしていますが
int $CubeSizeW = 1;
というように、宣言と代入を一度に行う事も出来ます。別々にしない方が行が短くなります。
intとfloatは数値を扱うので=の右側は数値を書くだけですが、文字列を扱うstringの場合は、"(文字列)"というようにダブルコーテーションで括っておきます。
string $text = "maya mel";
ベクトルの場合は3つの数値を扱うので、<<(数値),(数値),(数値)>>というように3つの数値を二重山括弧で括って、数値と数値の間にコンマを入れて区切ります。
vector $translate = <<1,1,1>>;
注意事項
上記では
int $pCubeSizeW;
$pCubeSizeW = 1;
polyCube -w $pCubeSizeW -h $pCubeSizeW -d $pCubeSizeW -sx 1 -sy 1 -sz 1 -ax 0 1 0 -cuv 4 -ch 1;
変数の宣言、変数の代入、コマンドを3行に分けて書きました。
変数の宣言、代入、コマンドの各行の最後には必ず;(セミコロン)を書いています。このセミコロンが1文の処理の区切りとなります。
例えば
int $pCubeSizeW
$pCubeSizeW = 1;
と1行目の変数の宣言の最後にセミコロンを書き忘れていると、これは
int $pCubeSizeW $pCubeSizeW = 1;
と書いているのと同じで、エラーが返ってきます。
反対に
polyCube -w $pCubeSizeW -h $pCubeSizeW -d $pCubeSizeW
-sx 1 -sy 1 -sz 1 -ax 0 1 0 -cuv 4 -ch 1;
と1つのコマンド内で改行をしていても、2行目の最後にセミコロンが入っているので
polyCube -w $pCubeSizeW -h $pCubeSizeW -d $pCubeSizeW -sx 1 -sy 1 -sz 1 -ax 0 1 0 -cuv 4 -ch 1;
と書いているのと同じなのでエラーにはなりません。
セミコロンを忘れていた時には、スクリプトエディタやコマンドラインに
// エラー: Line 2.11: Syntax error
というエラーメッセージが表示されます
このSyntax errorは、構文エラーと呼ばれるもので、プログラミングの書き方に沿っていない時に出るエラーです。この場合は、上記のように変数の宣言の最後にセミコロンが抜けているので出たエラーです。
Line 2.11は、エラーがある行を示しているので、その行の前後で、行の最後にセミコロンが抜けていないのかを確認してみましょう。
配列
上記の例では
int $CubeSizeW = 1;
string $text = "maya mel";
vector $translate = <<1,1,1>>;
というように、各変数毎に1つの値を代入していましたが、複数の値を代入する事も出来ます。
複数の値を代入する事が出来る変数の事を配列と呼びます。
配列の宣言
配列の変数の宣言の書き方は、変数名の後に[](大括弧)を付けます。これで変数に複数の値を代入する事が出来ます。
int $CubeSize[];
配列の代入
配列の変数への代入は、{値,値}というように値を中括弧で括って、値と値の間にコンマを入れて区切ります。
int $CubeSize[] = {1,1,1};
上記では、配列の変数で立方体の3辺を宣言して、各値を代入してます。
配列でよく使うのは、選択しているノードを取得したい時です。mayaのUI上で選択するとか、コマンドで名前から選択するとかした複数のノードに対して何らかの処理を加えたい時に、この選択したノードを配列の変数に代入します。
string $selectedNode[] = 'ls -sl';
lsは、シーン内のノードの名前を返すmelのコマンドです。名前を返すので、stringで文字列として宣言をしています。
lsコマンドの引数の-slは、-selectionの省略で選択中のノードをリストします。
コマンドを実行した結果を変数に代入する場合は、コマンドを'(コマンド文)'というようにシングルコーテーションで括っておきます。
上記では、選択中のノードの名前を$selectionNode[]という変数に代入をしています。
立方体と球と円柱を作成して、それらを選択した状態で
ls -sl;
を実行してみると、選択中の立方体と球と円柱の名前が返ってきました。
配列の値の取得
変数が配列ではない場合は変数の値は1つなので、変数をそのまま書いていましたが、配列の変数となると複数の値のどれを処理に使用するのか指定をする必要があります。
int $CubeSize[] = {1,2,3};
と立方体のサイズを配列の変数で宣言をした場合、指定をしなければ{1,2,3}のどの値が幅、高さ、深度になるのかがプログラムからは不明です。なので、配列の値が入っている順番を明記して、その順番に入っている値を取得します。
int $CubeSize[] = {1,2,3};
polyCube -w $CubeSize[0] -h $CubeSize[1] -d $CubeSize[2];
このコマンドを実行すると、幅が1、高さが2、深度が3の立方体(直方体)が作成されました。
配列の値が入っている順番の数字を配列の変数の大括弧の中に入れると、その順番の値を取得しています。
注意事項
配列の値が入っている順番は、前から0で始まります。
なので、上記の場合
[0]番目の値が1
[1]番目の値が2
[2]番目の値が3
となります。