デバッグ・調査
MaxScript チートシート の章一覧
「このオブジェクト、何ができるんだっけ?」を その場で調べる ための道具です。リファレンスを引く前に、まずリスナーで実測するのが速いことも多いです。
クラス・型を調べる
classOf $ -- そのオブジェクトのクラス(例: Box)
superClassOf $ -- スーパークラス(例: GeometryClass)
isKindOf $ GeometryClass -- 「〜の仲間か」を true/false で
classOf $.material -- マテリアルのクラス
- スーパークラスは Box や Sphere をまとめる大分類(GeometryClass・shape・light・camera・helper など)です。
superClassOf o == GeometryClassのように、種類でオブジェクトを絞るときに使います。 - ⚠️
classOf $ == GeometryClassは false です(classOfはちょうどのクラスを返す)。派生も含めて判定したいときはisKindOfを使います。
プロパティを一覧する
addModifier $ (Bend()) -- 例として Bend を付けておく
showProperties $ -- 変更できるプロパティ名を一覧表示
getPropNames $ -- プロパティ名を配列で取得(プログラムから扱える)
show $ -- showProperties の短縮形(出力は同じ)
showProperties $.bend -- モディファイヤのプロパティも同様に調べられる
- ⚠️
showPropertiesは 表示するだけ(戻り値はOK)。名前を配列で使いたいときはgetPropNamesを使います。 - ⚠️
showProperties $に出るのは Box などの 基本オブジェクトのプロパティだけ です。nameやposなどノード共通のものは出ません。モディファイヤやマテリアルは$.bend$.materialのように対象を直接渡します。 getPropNamesの戻り値は#heightのような Name 値の配列です。文字列として扱うときはp as stringにします。
プロパティ名のパターン検索
showProperties $ "*segs*" -- "segs" を含むプロパティだけ表示(lengthsegs など)
-- getPropNames の結果を自分で絞り込みたいとき
for p in (getPropNames $) where (matchPattern (p as string) pattern:"*segs*") collect p
- プロパティが多いクラスでは、ワイルドカードで 目的のプロパティだけ 絞り込めます。
getPropNamesはワイルドカード引数を取らないため、matchPatternとfor ... where ... collectを組み合わせてフィルタします。
関数・グローバルを横断検索する
apropos "render" -- 名前に "render" を含む関数・変数を一覧
apropos "get*" implicitWild:false -- 前方一致にしたいときは暗黙のワイルドカードを外す
showClass "*:modifier" -- スーパークラスが modifier のクラス(=モディファイヤ)を一覧
showClass "Box.*" -- Box クラスのプロパティ一覧(オブジェクトを作らなくても調べられる)
showInterfaces Editable_Poly -- クラスのインタフェース(メソッド群)を調べる
globalVars.gather() -- 宣言済みのグローバル変数の名前を配列で返す
aproposは 名前うろ覚えの関数を探す のに最適です。既定では名前に 含まれる ものをすべて拾います。出力は名前 (種別 クラス): 値の形です。リスナーに出た候補から当たりをつけます。showInterfacesの出力は Properties(プロパティ)・Methods(関数と引数の型)・Actions の 3 節に分かれます。$を渡すと基本オブジェクト分だけが出るので、モディファイヤなどは$.bendのように直接渡します。polyopやmeshopのような関数の集まり(構造体)はshowInterfacesでは調べられません(showInterfaces polyopはエラーになります)。リスナーでpolyopとだけ入力して実行すると、中の関数が一覧されます。polyop.getVertのような構造体の関数を探すときは、polyop.を付けずにapropos "getVert"と書きます("polyop.getVert"では見つかりません)。
値を出力して確認する
print $.name -- 値を 1 つ表示して改行
format "name=% pos=%\n" $.name $.pos -- 整形して表示
for o in selection do format "% : %\n" o.name (classOf o)
printは 1 つの値を改行付きで出します(文字列は"..."付き)。複数の値を並べて 1 行にしたいときはformatを使い、行末に\nを書きます。
例外を捕まえる(try-catch)
try
(
-- エラーが出るかもしれない処理
$DoesNotExist.pos = [0,0,0]
)
catch
(
format "エラー: %\n" (getCurrentException()) -- 例外メッセージを表示
)
- ⚠️ 原因を知りたいときは
getCurrentException()を必ず出力します。catch ()で握りつぶすと原因が分からなくなります。 - どの関数から呼ばれて失敗したかは
getCurrentExceptionStackTrace()で見られます。
処理時間・メモリを測る
t = timeStamp()
-- ...重い処理...
format "% ミリ秒\n" (timeStamp() - t) -- 経過時間(ms、0 時をまたぐ計測には使えない)
heapFree -- ヒープの空き容量(バイト)
heapSize -- 割り当て済みヒープの大きさ(heapSize += 50*1024*1024 で増やせる)
gc() -- ガベージコレクション(⚠️ アンドゥ履歴も消える)
gc light:true -- アンドゥ履歴を消さない GC(シーンのオブジェクトは回収しない)
サブアニメ(トラックビューの階層)をたどる
サブアニメ(subAnim)はトラックビューでオブジェクトの下に並ぶトラックのことです。
$.numSubs -- サブアニメの数
getSubAnimName $ 1 -- 1番目のサブアニメの名前
getSubAnim $ 1 -- 1番目のサブアニメ
for i = 1 to $.numSubs do format "% : %\n" i (getSubAnimName $ i) -- 名前を一覧
$.pos.controller -- サブアニメ関数ではなく、名前で降りるときはこう書く
落とし穴まとめ
showPropertiesは表示専用。配列で欲しいならgetPropNames。- 名前うろ覚えの関数は
aproposで横断検索する。 catchではgetCurrentException()を出力する。握りつぶさない。classOfはちょうどのクラス、isKindOfは派生も含めた判定。gc()はアンドゥ履歴を消す。
関連
- 調べた結果で対象を絞る: 「選択・取得」章
polyopを使った実例: 「メッシュ・ポリゴン」章
コメント