MaxScriptを書こう ~その6

2021年9月3日

for文を使ってselectionをループする

いきなりわけのわからない小見出しでひるみそうになったかもしれませんが、このページを読み終えるころには完全にわかるようになるのでそのまま進んでください。

前回説明したように、「選択されているもの」を対象にして何かを行うときには、$ではなくselectionを使うのが良いです。selectionには現在選択されているオブジェクトが全部入っていますので、そこから1つずつ取り出しては操作を行う、というような処理を行うことになります。

私たちのadjustPosは1つのオブジェクトに対して処理を行うようになっているので、選択されているすべてのオブジェクト(selectionのなかに入っているもの全部)から1つずつ取り出して処理を実行してやれば良い、ということになりますね。

まずはadjustPosは横へ置いておいて、selectionを使って中のオブジェクト1つ1つに対して何かする、というもののシンプルな例をやってみましょう。

スクリプトエディタで「ファイル→新規」として新しいエディタを開き、次のコードを入力してください。

for sel in selection do (
    print sel.name
)

シーン内のオブジェクトを選択しておいてこれを評価(Ctrl+E)すると、選択されているオブジェクトの名前がずらずらっとリスナーに出力されるはずです。

ここで使用した「for」というのはよく「for文」と呼ばれるもので、MaxScript以外のほかのプログラム言語にもたいてい存在しています。for文は一般的に何らかの処理を繰り返すときに使用され、「ループ構文」などと呼ばれるものの一つです。

MaxScriptのfor文には大きく分けて2種類の書き方がありますが、ここで使用したのはそのうちの1つです。コレクションオブジェクトに対して使用する場合に使う書き方ですので覚えてしまいましょう。

for (1つ1つを格納するための変数名) in (コレクションオブジェクト) do (
    実行する処理(1つ1つを格納した変数名を使用できる)
)

ここで使っている「1つ1つを格納するための変数名」はなんでも構いません。わかりやすいもので良いでしょう。ここではselectionのなかの1つなのでsel(selected object の略のつもり)という変数名をつけました。

変数名は3dsmax内で既に使われている名前でない限りは何を使っても構いません。逆に、例えばビルトイン関数の名前であるfloorのようなものに他の何かを代入することはできないので、floorは変数名に使えません。

この書き方と上のコードを比べてみると、selという変数にselectionから取り出したオブジェクトを代入し、print sel.nameとすることでその名前をリスナーに出力している、ということになります。

関数を書き換えてみる

ではこのfor文を使ってadjustPosを書き換えてみましょう。もとのadjustPosで$を使っていた部分に、この「1つ1つを格納するための変数名」を使えば良いことになります。

function adjustPos = (
    for sel in selection do (
        sel.pos.x = floor sel.pos.x
        sel.pos.y = floor sel.pos.y
        sel.pos.z = floor sel.pos.z
    )
)

関数を書き直したら改めて評価(Ctrl+E)します。

さあ、シーン内のオブジェクトを複数選択してadjustPos()を実行してみましょう。

めでたく複数のオブジェクトに対して実行することができました。

次回は関数のあり方について少し学び、さらに汎用性の高いものに改善していきましょう。

今回のまとめ

  1. 繰り返しの処理には「ループ構文」の一種である「for文」を使う
  2. for文を使うことでコレクションオブジェクトの中の個々のオブジェクトを操作できる

前:MaxScriptを書こう ~その5

次:MaxScriptを書こう ~その7