特殊な表記
解説中で、$Box001 というように '$' をジオメトリ名の頭に付けています。これは、Box001 というジオメトリを表す変数のことで、MAXScript では通常の変数と区別するため、このような表記方法を取っています。ちょっと分かり辛いのでまとめてみます;
print $Box001.Name -- "Box001" と表示される
$Box001.Name = "newName"
print $newName.Name -- "newName" と表示される
print $Box001.Name -- エラーになる
print newName -- undefined
また、ジオメトリは '*' を使って配列として取得することもできます。試しに、
for box in $Box* do (
print box.Name
)
......と実行してみてください。シーンの中にあるジオメトリのうち、頭に "Box" と名前の付くものだけを選び出すことができました。これも最初の例の応用です。
for をさらに使いこなしてみる
名前を表示するだけなのも飽きてきました。もうちょっと別の使い方も考えてみます。
せっかくCGソフトなので、オブジェクトを操作してみましょう。
100 個のオブジェクトを配置してみます。
for i=0 to 9 do (
for j=0 to 9 do (
x = i * 10
y = j * 10
box = Box pos:[x, y, 0] length:1 width:1 height:1
box.Name = "Box_" + (i as String) + "_" + (j as String)
)
)
......何だかいきなり複雑になってしまいました。ですが、ひとつひとつの構成要素をじっくり見ていけば理解できますよ。
一番大きな違いは、for 文の中に for 文が入っていることです。さらに、内側の for 文の中身もよく分からない記号が沢山入っています。
こういう時には、MAXScript エディタの機能を使います。

内側の for の左にある四角の部分をクリックしてみてください。すると!! for が折り畳まれて、 シンプルな見た目になりました。

さらに外側の for の中身も折り畳んでみてください。シンプルな for だけのブロックになりました。

こうして見ると、外側の for によって i が 0 から 9 まで変化しながら毎回内側の for が
呼ばれていることが判ります。
これを理解できてしまえば、後は一番内側のブロックを解析するだけです。
x = i * 10
y = j * 10
「x」と「y」という名前の変数にループで加算される値を 10 倍して代入しています。
box = Box pos:[x, y, 0] length:1 width:1 height:1
......Box ジオメトリを生成しています。 pos や length, width, height は Box を作る際のオプションです。先ほどシーンを再構築するために MAXScript リスナーの値をコピー&ペーストした時にもありましたね。
GUI から作るとこれ以外にも様々なオプションがつきますが、必須ではないので省略しています。
box.Name = "Box_" + (i as String) + "_" + (j as String)
作成した「Box」の名前を付けています。 文字列は '+' を使って繋げることができます。
「 (i as String) 」という部分は、i という数値を文字列に変換しています。
数値と文字列は、画面で見たときにはほとんど違いがありませんが、コンピュータからみたら大きな違いがあります。
a = 1 -- a には数値の 1 が入る
b = a + a -- 数値を足しているので b は 2
a = "1" -- a には文字列の 1 が入る
b = a + a -- 文字列を足しているので b は "11"
人間が計算をする時はその場に応じてその値が数字なのか文字列なのか、それらをどのように扱ったらいいのか判断をしながら処理ができますが、コンピュータに処理をさせる時には厳密に指示をしなければいけません。そのため、わざわざ明示的に文字列に変換しているのです。
これは数値や文字列に限らず、プログラミングを行う上でとても大事なことになってきます。プログラムがなぜかエラーになるのかとか、マニュアルで調べた機能をどのように使うのか分からない時は、プログラム上で今どのような形式のデータを扱っているのか注意すると問題が解決することが多々あります。
因みに、ループで selection から 取り出した s の中には、数値でも文字列でもない、ジオメトリという形式のデータが入っていました。そして、今解説中の Box にも同じ形式のデータが入っています。
マニュアルで「Box」を調べてみてください。検索すると、"Box: GeometryClass" という項目が見つかります。このページを見ると、Box に指定できるプロパティの一覧を知ることができます。そこを見てみると、Box ジオメトリを生成するときに使用した「length」、「width」、「height」などのオプションもあります。
それ以外の、「pos」や「Name」などはどこにあるのでしょうか? これは[ノードの共通プロパティ、演算子、メソッド]にあります。
pos や Name は Box に特有のものではなく、Sphere や Plane にもあります。Max ではこれらを総称して「ノード」と呼び、ノードは共通のプロパティを持っています。ノードの一覧は[GeometryClass: Node]の項目で見ることができます。
今、自分がどのような種類のデータを扱っているか知りたいときに便利なのが classOf メソッドです。
classOf <変数、オブジェクトなど> と実行すると、データの種類を表示してくれます。

データの種類が判れば、それを元にマニュアルを参照して何ができるのかを調べたり、スクリプト内でどのような処理がされているのかを理解することができます。
そのジオメトリにどのようなプロパティがあるかなど、より詳細な内容を知りたければ「showProperties」のようなメソッドを使います。これらの使い方は次回以降、必要に応じて解説します。興味のある方はリファレンスの[クラスとオブジェクトの調査関数]を参照してみてください。
さて、解説が長くなってしまいましたが、これで全ての内容が理解できるはずです。いかがでしょうか?
今回解説したループと、MAXScript リスナーを上手に使えば今まで手で何百回と繰り返してきた単純作業をスクリプトに任せることができるようになります。ぜひ、活用してみてください。次回以降は、より具体的な応用例をご紹介していきます。
TEXT_痴山紘史(JCGS)
映像制作のためのパイプライン構築をはじめ、技術提供を行なっていくエンジニア集団、「JCGS(日本CGサービス)」代表取締役......というのは表の顔で、実態は飲み会とCG関連の技術が好きなただのCGオタク。
http://philosy.com/blog