MaxScriptを書こう ~その9

2021年9月3日

ツールを改良する

前回までに作ったadjustPosツールを改良しましょう。一口に改良と言っても改良の余地はたくさんあるので、どこから手をつけたものか迷いますね。何度か使ってみて、どこが使いにくいか、どこが物足りないか、といったことを洗い出し、それぞれどういう方向で改善するかを考えましょう。

まず私が気になったのは、このツールは実行したときにどうなったのかよくわからない、という点です。例えば何も選択せずに実行ボタンを押すと、何も実行されずに終わります。厳密にはselectionの中身が無いため、for文の中に入ることなく処理が終了します。

そこで、何も選択されていない場合はその旨をメッセージで知らせ、実行した場合は実行しましたよというメッセージを表示させるようにしてみましょう。

メッセージを表示する

メッセージを表示するにはmessageBoxというビルトイン関数を使います。この関数は以下のように実行することで、メッセージを表示した小窓を表示します。

messageBox "メッセージです"

これを実行すると次のようになります。

これを使ってメッセージを表示しましょう。

rollout ro_adjust_pos "位置の値を丸めるツール" (
    button btn_exec "実行!"

    on btn_exec pressed do (
        if selection.count == 0 do (
            messageBox "操作するオブジェクトを選択してください"
            return false
        )
        for sel in selection do (
            adjustPos sel
        )
        messageBox "完了しました。"
    )
)

createDialog ro_adjust_pos

※ロールアウトを評価する前に関数adjustPosを評価しておいてください。

実にあっさりと新しい要素を使ってしまいました。それは5行目にあるifです。ifはif文と呼ばれ、for文と同様、ほとんどのプログラム言語にあります。条件分岐構文と呼ばれるものの一つで、その名のとおり、ある条件を満たした場合の処理と、満たさない場合の処理を分岐することができます。

if文を使う(条件分岐構文)

if文の書き方は以下のようになります。

--条件を満たした場合だけ実行する、というケース
if (条件式) do (
    条件を満たした場合の処理
)

--条件を満たさなかった場合は違う処理を行うケース
if (条件式) then (
    条件を満たした場合の処理
) else (
    条件を満たさなかった場合の処理
)

これを踏まえて上のコードの中でif文のところだけを取り出してみましょう。

if selection.count == 0 do (
    messageBox "操作するオブジェクトを選択してください"
    return false
)

これは、もしselection.count(選択されているオブジェクトの数)が0に等しい(==は等しいという意味の記号です)場合、messageBoxというビルトイン関数に"操作するオブジェクトを選択してください"という文字列を引数として渡して実行し、falseを返す、という意味になります。

return というのはMaxScriptでは関数から何かを返し、処理を抜ける際に使うキーワードです。ここで返しているfalseというのは真偽値(ブール値)と呼ばれる値の1つで、処理に失敗した場合などに返される値です。この辺は追々開設していくので、今のところは関数の途中で何らかの値をreturnするとそこで処理が終わる、と思ってください。

ちょっとまて、関数だったのか?と思われますよね。

今、このif文が書いてあった場所はボタンのイベントハンドラの中でした。イベントハンドラは関数なのでしょうか。完全にイコールかと言えば厳密には違いますが、広義ではイベントハンドラも関数の一種と考えて良いでしょう。イベントハンドラを途中で中断したい場合も、returnで何か値を返して抜ければよい、ということになります。

ちなみに、CやC++などの言語では単にreturnとして、何も値を返さずに処理を抜けることができますが、MaxScriptでは戻り値のないreturnは認められていません。途中で処理を終えたいときは必ず何らかの値を返す必要があります。

どんな値を返しても良いので例えばreturn 2とかいうことも可能ですが、わけがわからなくなるので無意味な値は返さないようにしましょう。一般には真偽値(trueまたはfalse)や(OK)などを返すことが多いです。今回の場合、selection.countが0の場合は処理が行われないので、OKなどを返すと誤解を招くのでfalseを返すことにしました。

条件式が満たされない場合、そのブロックは実行されません。今回のケースではselection.countが0でない場合(つまり選択されているオブジェクトがある場合)はif文の中身は実行されず、処理は次のfor文へ移行します。

逆に条件式を満たした場合(つまり選択されているオブジェクトが無い場合)はif文の中が実行され、そこにreturnがあるのでそこで処理が終了し、その後の部分は実行されない、ということになります。

もしここにreturnが無かったら、if文の部分を実行したあとに次の行へ進行し、移行の処理が実行されることになります。

これで、選択されているものがなければメッセージを表示し、選択されているものがある場合は処理を行って「完了しました」というメッセージを表示するという機能が実装できました。

次回はこのメッセージにもう一工夫してみましょう。

今回のまとめ

  • 条件によって処理をわけたい場合はif文を使う
  • メッセージを表示するにはmessageBoxを使う
  • 関数(やそれに類するもの)を途中で抜けるにはreturnを使う

前:MaxScriptを書こう ~その8

次:MaxScriptを書こう ~その10