MaxScriptを書こう ~その5

2021年9月3日

$に潜む罠

前回作成したadjustPosという関数では、「現在選択されているもの」という意味で「$」を使用していました。この$は便利ですが実はいろいろな罠が潜んでいるので注意を要します。

まず、シーン内にもう一つ何でも良いのでオブジェクトを生成し、先にあった球体と新たに作ったオブジェクトを両方とも選択してadjustPosを実行してみてください。

このように、エラーになってしまいます。

$は「現在選択されているもの」を表す便利な記号ですが、選択されているものが何かによって挙動が変化します。なんにでも変身できる存在なのです。

複数のオブジェクトを選択した場合、$はselectionというコレクションオブジェクトを指すようになります。コレクションオブジェクトというのは複数のデータを格納した入れ物のようなものだと思ってください。

赤い字で表示されたエラーメッセージは、「$selectionというオブジェクトにはposというプロパティが無いよ」というような意味です。無いものにアクセスしようとしたのでエラーになったわけですね。

では選択状態は現状のまま、リスナーに次のように入力してみてください。

$.count

2と表示されました。これは$が指している$selectionというオブジェクトのcountというプロパティが2ですよ、という意味です。コレクションオブジェクトが持つcountというプロパティにはそのコレクション内にオブジェクトがいくつ入っているかを表しています。

つまりここでの2は、「現在選択されているもの」は2個ありますよ、という意味になるわけです。

ためしに選択を1つだけにしてリスナーに$.countと入力してみましょう。今度はエラーになりますね。選択が1つだけの場合、$はその1つのオブジェクトそのものを指しています。選択が複数になると、選択されている全てのオブジェクトを格納したコレクションオブジェクトを指すようになります。

このように「$」という記号は便利ですが、中に何が入っているかわからないため、なるべく使わないほうが良いでしょう。

※リスナーでちょっとした操作を行う程度の用途であれば「$」は便利です。何が入っているかわかった上で使えるケースではどんどん使って構いません。

「選択されているもの」にはselectionを使う

現在、adjustPosはオブジェクトを1つだけ選択した状態で実行すればちゃんと動きますが、選択が複数だったり、何も選択されていなかったりするとエラーになります。そこでまず、選択が複数の場合に対応させてみましょう。

複数のオブジェクトが選択されていた場合、やはりその全てのオブジェクトに対して座標の操作が実行されてほしいですよね。そこで、複数のオブジェクトが選択されていたら、その1つ1つに対してadjustPosが実行されるようにしましょう。

選択されているものを対象にしたい場合は、「$」ではなく「selection」という名前を使いましょう。selectionは複数選択の場合に$が指していた$selectionというオブジェクトを指している名前です。$よりもselectionのほうが使いやすいのは、単数選択の場合でもselectionはその選択されている1つだけが格納されたコレクションオブジェクトでいてくれる、という点です。

確認してみましょう。

オブジェクトを複数選択してリスナーで以下を実行します。

selection.count

選択されているオブジェクトの個数が表示されますね。さらに、選択を1つだけにして同じように実行してみてください。

$を使ったときはエラーになりましたが、selection.countであれば単数選択でも1と正しく表示されます。

さらに、何も選択せずに実行すれば0と表示されます。このようにselectionを使うと、選択されているオブジェクトがいくつであろうと、エラーにならずに常にコレクションオブジェクトとして振舞ってくれます。このため、スクリプトとして使う場合には「$」ではなくselectionを使ったほうが良いのです。

次回はこのselectionを用いてadjustPosを複数選択に対応させましょう。

今回のまとめ

  1. $は選択されているものの内容によって振る舞いが変化する
  2. スクリプトでは$ではなくselectionを使おう

前:MaxScriptを書こう その4

次:MaxScriptを書こう その6