MaxScriptを書こう ~その12

2021年9月3日

スクリプトファイルはどこに保存すればよいか

さて、今回はツール内で使う汎用関数を別のファイルに保存しておいて呼び出して使う、ということをやろうと思うわけですが、そもそもスクリプトファイルはどこに保存するのが良いのでしょうか。

3dsmaxでスクリプトファイルを保存する場所としては以下のような候補があります。

  • ユーザスクリプトフォルダ
  • スクリプトフォルダ
  • ユーザスタートアップフォルダ
  • スタートアップフォルダ
  • その他任意の場所

3dsmaxで推奨されているのは上の4つです。要約すれば、スクリプトフォルダかスタートアップフォルダで、全ユーザを対象とするか、自分だけを対象とするか、という違いになります。

3dsmaxではPCのログインユーザごとにユーザフォルダが作成されます。このユーザフォルダの中にスクリプトフォルダやスタートアップフォルダがあり、そのユーザでログインしている時に有効になります。一般にはオリジナルのスクリプトはここに保存するのが良いです。

ユーザ固有ではないスクリプトフォルダやスタートアップフォルダは3dsmaxのインストールフォルダ内にあります。こちらに入れると、そのPCを使う全てのユーザが共通で使用できることになります。

スタートアップフォルダ

スタートアップフォルダに入れたスクリプトファイルは、3dsmaxの起動時に自動的に読み込まれ、評価されます。つまり、関数を記述したファイルをスタートアップフォルダに入れておけば、起動後、その関数はいつでも使える状態になっている、ということになります。

インストールフォルダにあるスタートアップフォルダであれば、そのPCの全てのユーザに関して、起動時に実行されます。

ユーザスタートアップフォルダの方は、そのユーザでログインしている時のみ起動時に実行されます。

※そのPCを使用するユーザが1人しかいない場合はどちらでもほとんど差はありません。

スクリプトフォルダ

スクリプトフォルダに入れたものは、特に自動的に実行されたりはしません。汎用関数のようなもの以外の一般的なスクリプトファイルは、通常必要な時に実行すれば良いため、スタートアップフォルダではなくスクリプトフォルダの方に保存します。

これもユーザスクリプトフォルダであれば当該ユーザでログインしているときだけアクセスできるようになります。

スクリプト関連フォルダへのアクセス

スクリプトフォルダ、スタートアップフォルダなどへは3dsmax上から簡単にアクセスすることができます。それぞれ以下のような名前でアクセスすることになります。

  • スクリプトフォルダ: #scripts
  • スタートアップフォルダ: #startup
  • ユーザスクリプトフォルダ: #userscripts
  • ユーザスタートアップフォルダ: #userstartup

これらの名前をビルトイン関数getDirの引数に渡すと、そのフォルダへのフルパスが返ってきます。やってみましょう。以下を1行ずつリスナーで実行してみてください。

getDir #scripts

getDir #startupScripts

getDir #userScripts

getDir #userStartupScripts

結果は以下のようになります。

スクリプトファイルは他の任意の場所に保存しても構わないのですが、3dsmaxが推奨している場所に保存すると、このようにスクリプト上から簡単にアクセスすることができるので重宝なのです。

スクリプトからスクリプトファイルを読み込む

スクリプトからスクリプトファイルを読み込む方法には2種類あります。

FileInを使う

1つはFileInというビルトイン関数を使う方法です。FileIn関数は引数としてスクリプトファイルのパスを受け取り、そのスクリプトファイルの中身を評価します。

では例のadjustPos()をユーザスクリプトフォルダにcommonLib.ms(共有ライブラリ、ぐらいの意味です)という名前で保存し、以下を実行してみてください。

FileIn (getDir #userScripts + "\\commonLib.ms")

getDirに#userScriptsを渡すことで、ユーザスクリプトフォルダへのフルパスが文字列として返ってきます。これにファイル名の部分を足したものをFileIn関数に渡しています。

ここで、ファイルパスの区切りは\ですが、\には特別な意味があるため、文字列内に\を書きたいときは\\と2つ並べて書く必要があることに注意してください。

※\はフォントによってバックスラッシュになったり円マークになったりしますが同じものを意味しています。

実行するとリスナーにはadjustPos()と表示され、関数の評価が実行されたと思います。

includeを使う

もう一つはincludeを使う方法です。こちらはFileInとは違い、ファイルの中身は評価されません。評価されるのではなく、中身がそのまま読み込まれます。やってみましょう。

include "$userScripts\\commonLib.ms"

またいきなり初めて見る書き方を使ってしまいました。ここではgetDirでフルパスを取得するのではなく、文字列の中に$userScriptsと書いています。このような表記方法も使うことができます。

もちろん、getDirでフルパスを取得してそれをincludeに渡しても問題ありません。

実行すると以下のようになります。

includeに渡したファイルの中身が展開され、表示されました。

FileInとincludeの使い分けの指針

外部のスクリプトファイルを読み込む方法としてFileInとincludeがあることを紹介しましたが、どちらを使えば良いのでしょうか。

これはまさにケース・バイ・ケースです。この2つは内容が異なるため、それぞれの用途に合わせて使用することになります。

まず大きな違いとして、FileInは実行した時にすぐファイルの中身が評価されます。このとき、評価される内容はファイルの内容そのままなので、今回のように関数だけが書いてある場合、その関数はグローバルスペースに宣言されることになります。

対してincludeの方はその場所にファイルの中身が展開される、ということなので、展開した後それを評価するまで評価は行われません。

この場合、例えばブロックの中にincludeを書けば、ファイル内の関数はそのブロック内で宣言されることになり、スコープを制限することができます。このため、グローバルスペースで宣言する必要がない、あるいは宣言したくないものについては、includeを使用して読み込むのが良いでしょう。

このツールとしては、includeでrollout内にadjustPos()を宣言する方を採用しましょう。

これでめでたく、adjustPosツールが形になりました。

次回は、位置の値を丸める処理そのものをもう少し見直してみましょう。

今回のまとめ

  • スクリプトからスクリプトファイルを読み込む方法にはFileInとincludeがある
  • FileInでは書いた場所でスクリプトファイルが評価され、includeではその場所に展開される
  • FileInで読み込んだスクリプトはグローバルスコープで評価したのと同じ結果になる
  • includeで読み込んだスクリプトはその時点では評価されず、全体として評価されるのでincludeした場所に応じてスコープが適用される

前:MaxScriptを書こう ~その11

次:MaxScriptを書こう ~その13