この記事はアドベントカレンダーMaya 2025の1日目の記事です。
毎年すごい人たちがすごい記事を上げていらっしゃいますが、ちょっとした小ネタでもよいとあったので参加させていただきました。
主にキャラクターアーティストさん向けに、『TAにツール化を依頼するほどではないけど、スクリプトを書かないとできないちょっとした小ネタ』を紹介していきます。
基本的にPythonです。
アウトライナで特定の種類のノードだけ選択する
どんな状況を想定しているかと言いますと
- ジョイントにコンストレインが混在しており、ジョイントだけ選択したい
- キャラのリグの中にあるnurbsカーブコントローラだけ選択したい
- ポリゴンメッシュ化し終わったのでゴミのnurbsサーフェスはまとめて捨てたい
他にも色々シチュエーションはあると思いますが「特定の種類のノードだけ選択できないかな~」とか、「アウトライナで地道にポチポチ選択してもいいけど、結構な数があって面倒だな~」みたいなこと、わりかしありますよね?
import maya.cmds as cmds
nodes = cmds.ls(sl=True, dag=True, type="nurbsCurve")
#========================================
# 用途に合わせてどれかひとつ実行
#========================================
# 一括選択
cmds.select(nodes)
# 一括削除
cmds.delete(nodes)
# 一括ペアレント
# 下記例はparentGroupというノードの子にします
cmds.parent(nodes, "parentGroup")
nodes = cmds.ls(sl=True, dag=True, type="nurbsCurve")は、選択中のノード以下の階層を捜査して、"nurbsCurve"だけ選んでnodesという名前の箱にまとめておく、という処理です。type=""に入れる文字列を変更することで、好きなノードタイプを保管できます。
保管しておく箱のことは「変数」と言います。
一括処理するために箱をまるごと処理に渡したり、箱から一つずつ要素を取り出して処理に渡したりできます。便利ですね。
ところで、「いやいやアンタはTAだからtype=""に入れるタイプ名を知ってるでしょうけど、私はノードの正式名称なんて気にしたことないわ!」とお思いですよね?
実は、これはGUIで簡単に確認できます。

このように、該当のオブジェクトを選択した状態でアトリビュートエディタを開くと、赤い四角で囲った位置にノードタイプが表示されます。

他にも、ノードエディタでノードの上にマウスを重ねると、Type:locatorのようにノードタイプが表示されます。
もしくは、Pythonスクリプトでノードタイプを調べることもできます。
import maya.cmds as cmds
nodes = cmds.ls(sl=True, dag=True)
for node in nodes:
type = cmds.nodeType(node)
print(f"{node}'s type is '{type}'.")
皆様も好きなノードを一括処理しましょう!
上に書いた処理以外にも、実際にGUIメニューからやりたいことを実行して、スクリプトエディタのログに出力されたコマンドをPython形式に書き直してあげることで一括処理ができると思います。
もし実行したいコマンドがリストを受け付けない場合は、リストをfor文で回してノード1個ずつ実行してあげる必要があるかもしれません。
for node in nodes:
# ここで1こずつ処理
カレントUVSetを一括で変更する
チェック業務をされているリードの皆様におかれましては、UVSetが複数ある案件ではポチポチすべてのUVSetを確認されているかと存じます。
すべてのメッシュですべてのUVSetを確認すると、カレントUVSetがメッシュごとにバラバラになってしまうことがありますよね。
提出されたデータをそのまま渡すならいいですが、手元で触ったデータでUVSetだけ特定の名前のUVSetに一括で揃えて渡したい、ってこともあるかと思います。
その場合は、以下のスクリプトで一括変更が可能です。
import maya.cmds as cmds
# 使い方:複数メッシュを選択して、ダイアログにUVSet名を入力する
uvset_dialog = cmds.promptDialog(message="What is UVSet name?", button="Enter", style="text")
if uvset_dialog:
uvset_name = cmds.promptDialog(query=True, text=True)
meshes = cmds.ls(sl=True, dag=True, type="mesh")
for mesh in meshes:
cmds.polyUVSet(cuv=True, uvSet=uvset_name)
※↑公開後ミスに気づいたのでちょっと修正しました。すみません
モデリングポーズ⇔出荷ポーズの切り替え
キャラモデラーの方は基本的にスカルプトやテクスチャ作業はリラックスポーズで行うことが多いですよね。
しかし、アニメーターやリガーへモデルを出荷する際の出荷ポーズは、AスタンスやTスタンスになっているかと思います。
現場によっては、既定のスタンスになってないとチェックツールではじかれて、勝手に直されたりすることもあるかと思いますが、手動で出荷ポーズへ変更する場合どうしているでしょう。
キャラモデラー目線でオペレーションを考えてみると、
- 出荷したいバインド済みメッシュとジョイントがある
- StudioLibraryでリラックスポーズから出荷ポーズに変更
- メッシュとジョイントを複製し、複製済み同士で再バインド
- 複製前のメッシュからウェイトをコピー
- 出荷
になりそうです。
これはかなり面倒くさい……。
実はですね、バインドポーズは上書きができます。
import maya.cmds as cmds
# 使い方:rootジョイントを選択してスクリプトを実行
joints = cmds.ls(sl=True, type="joint")
bindpose = cmds.listConnections(f"{joints[0]}.bindPose", s=False, d=True)[0]
cmds.dagPose(bp=True, save=True)
cmds.delete(bindpose)
上のコードでは、バインドポーズの新規作成と、古いバインドポーズの削除をします。
こうすることで、GUI上の再バインドとスキンウェイトのコピーをすっ飛ばして出荷ポーズを作成できます。工程がぐっと減るので、ヒューマンエラーも減りそうです。
おわり
もしかしたら、GUIからできることなのかもしれませんが、Pythonスクリプトの入門としてもとっつきやすいネタをピックアップしてみました。
これくらいの行数なら何を書いてあるかわかると思いますし、これを機にスクリプトを書く方が増えたら嬉しいです。
ここまでお読みくださり、ありがとうございました。