リファレンス / 3ds Max / MaxScript チートシート

選択・取得

  • 3ds Max
  • MaxScript
  • チートシート
MaxScript チートシート の章一覧

スクリプトの起点になる「対象を手に入れる」操作をまとめます。 選択を変える系(select)と、選択せずに集める系(for ... collect)を使い分けるのがコツです。

全部・現在の選択を取得する

objects          -- シーン内の全ノード(コレクション)
selection        -- 現在選択されているノード
$                -- selection と同じ(現在の選択)
selection.count  -- 選択数
objects.count    -- 全ノード数
  • objects / selection選択を変えずに中身を読む ための入口です。
  • ⚠️ objects はジオメトリだけでなく、ライト・カメラ・ヘルパーなど 全ノード を含みます。種類で絞るには後述のフィルタを使います。

種類ごとの予約コレクション

objects と同じように、種類別にまとまった組み込みコレクション が予約語として用意されています。これを使えばクラス判定を書かずに目的の種類だけを取得できます。

geometry     -- 全ジオメトリ(Box / Sphere / Editable_Poly ...)
lights       -- 全ライト
cameras      -- 全カメラ
shapes       -- 全シェイプ(スプライン / テキスト ...)
helpers      -- 全ヘルパー(Dummy / Point ...)
spacewarps   -- 全スペースワープ
systems      -- 全システム(Bones / Biped ...)

lights.count                 -- ライトの数を数える
for c in cameras do print c.name  -- カメラ名を列挙
select geometry              -- ジオメトリだけを選択
コレクション 取得対象 相当する絞り込み
objects 全ノード
geometry ジオメトリ全般 superClassOf o == GeometryClass
lights ライト全般 superClassOf o == light
cameras カメラ全般 superClassOf o == camera
shapes シェイプ全般 superClassOf o == shape
helpers ヘルパー全般 superClassOf o == helper
spacewarps スペースワープ全般 superClassOf o == SpacewarpObject
systems システム全般
  • いずれも objects と同じく 選択を変えずに読める コレクションで、.countfor ... do がそのまま使えます。
  • ⚠️ lights / cameras には ターゲット(注視点)オブジェクトも含まれます。ライト本体だけを処理したいときは where classOf o != TargetobjectsuperClassOf o == light で除外します。
  • ⚠️ さらに細かく「Box だけ」「Omni ライトだけ」が欲しいときは、これらに対して後述の where classOf o == ... を重ねます。

名前で1つ取得する

$Box001                          -- 名前で直接指定(存在しないとエラーではなく undefined 扱い)
getNodeByName "Box001"           -- 文字列(変数)から取得。無ければ undefined
getNodeByName "box001" ignoreCase:false  -- 大文字小文字を厳密に区別(既定 true = 区別しない)
getNodeByName "Box001" exact:true         -- ワイルドカードを使わず完全一致で照合(既定 false)
  • 名前が 変数や文字列 になっているときは getNodeByName を使います。$ の後ろには変数を書けません。
  • ⚠️ 大文字小文字を制御するのは ignoreCase:、ワイルドカードの有無を制御するのは exact: です。混同しないよう注意します。
  • ⚠️ 同名ノードが複数あると、最初に見つかった1つだけが返ります。

名前のパターンでまとめて取得する

$Box*            -- 「Box」で始まる全ノード(ワイルドカード)
$*_low           -- 「_low」で終わる全ノード
($Box* as array) -- 配列にして for で回しやすくする
  • *(任意の文字列)と ?(任意の1文字)が使えます。
  • 結果は ObjectSet なので、as array で配列化すると扱いやすくなります。

選択を操作する

select $Box001        -- 選択を置き換える
selectMore $Sphere001 -- 現在の選択に追加する
deselect $Box001      -- 選択から外す
select objects        -- 全選択
clearSelection()      -- 全解除
selectByName()        -- 名前で選択するダイアログを開く
関数 動作
select <obj> 選択を 置き換え
selectMore <obj> 選択に 追加
deselect <obj> 選択から 除外
clearSelection() すべて解除
  • select には単体ノードでも配列でも $Box* でも渡せます(例: select #($Box001, $Sphere001))。

種類(クラス)で絞り込む

-- Box だけを集める(選択は変えない)
for o in objects where classOf o == Box collect o

-- ジオメトリ全般を集める(球でも円柱でもメッシュでも)
for o in objects where superClassOf o == GeometryClass collect o

-- ライトだけを選択する
select (for o in objects where superClassOf o == light collect o)
判定 用途
classOf o == Box そのクラスちょうど(派生は含めない)
superClassOf o == GeometryClass ジオメトリ全般
isKindOf o GeometryClass 派生も含めて「〜の仲間か」
  • 代表的なスーパークラス: GeometryClass / shape / light / camera / helper
  • ⚠️ classOf o == Editable_Poly のように、編集後はクラスが変わる点に注意(元が Box でも編集ポリゴン化すると Box では引っかかりません)。

条件で絞り込む(表示・色・レイヤーなど)

-- 非表示・凍結を除いた「いま触れる」ノード
for o in objects where (not o.isHidden) and (not o.isFrozen) collect o

-- ワイヤカラーが赤のノード
for o in objects where o.wirecolor == red collect o

-- 特定レイヤーに属するノード
lay = LayerManager.getLayerFromName "Layer01"
nodesOnLayer = #()
lay.nodes &nodesOnLayer   -- 参照渡しで配列に格納される
nodesOnLayer
  • where の後ろには任意の条件式を書けます。複数条件は and / or でつなぎます。
  • ⚠️ layer.nodes参照渡し(&)で受け取る点が独特です。戻り値ではなく引数の配列が書き換わります。

名前付き選択セット

selectionSets["ExportSet"] = selection   -- 現在の選択をセットとして保存
select selectionSets["ExportSet"]        -- セットを呼び出して選択
selectionSets.count                      -- セット数
  • UI の「名前付き選択セット」と同じものを読み書きできます。
  • ⚠️ セット名は大文字小文字を区別します。存在しない名前を読むと undefined です。

ループ中に選択を変える / 削除するときの定石

-- ✕ ループ中に対象を消すと取りこぼす
-- for o in selection do delete o

-- ◯ いったん配列のコピーを取ってから回す
for o in (getCurrentSelection()) do delete o
-- または
for o in (selection as array) do delete o
  • getCurrentSelection() は選択の スナップショット(配列コピー) を返します。
  • ⚠️ selectionobjects回しながら中身を増減 させると、取りこぼしやエラーの原因になります。削除・再選択を伴うループでは必ずコピーしてから回します。

落とし穴まとめ

  • $Name には変数を書けない。変数・文字列からは getNodeByName を使う。
  • objects は全ノード。ジオメトリだけが欲しいなら superClassOf == GeometryClass で絞る。
  • 編集系モディファイアやコンバートでクラスが変わる(BoxEditable_Poly など)。
  • 削除・再選択を伴うループは getCurrentSelection() でコピーしてから回す。

関連

← MaxScript チートシート へ