【Maya】DCCツールを作ってみよう -入門編-

こんにちは、はじめまして!動物が超好きだけど悲しき哉…犬猫アレルギー持ちの田中です。

今回は、Mayaのツールを作ってみたいけど、どこからやればいいの?という初学者向けに、簡単なMayaツールの作り方のアレコレをできるだけ丁寧に解説したいと思います。
今後のMayaツールを使った快適な制作フローの一助となれば幸いです。

目次

 

使用する環境

・Mayaのバージョン: Maya2024

 

Mayaツール作成の2大言語について

はじめにMayaのツールは、主に以下の2つの言語で作ります
 ・MEL
 ・Python

他にもOpenMayaというAPIもありますが、難易度が上がるため今回は取り上げません。
MELとPythonは以下のような違いがあります。
それぞれいいところがあるので、自分に合った言語で作っていきましょう!
(なお、今回はPythonで作成していきます)

ちなみに上のMELのメリットの項目で、Maya標準のツール機能を実行するとMELコマンドが出てくることがあるとありますが、
ツール実行時に
・処理に必要な複数のコマンド(MayaのツールUIを変更するコマンドなど)
・単なる実行結果
・プロシージャ(Mayaの複数のMELが組み合わさってできた組み込み関数)
など同時に色々表示することもあるのでコマンドなのか見極めることも大事になります。

MELからPythonへの変換方法についてはこちらの記事で紹介しておりますので、チェックしてみてください!
【Maya】超初心者向け、MELからPythonへのコマンド変更方法

 

作成するツール

今回はリネームツールをPythonで作成してみましょう
選択したモデルすべてに、プリフィックスをつけて
指定のプリフィックス + モデル名 にリネームするだけの単純な設計のツールになります

 

ツールを作るための検証

MELのコマンドを確認するとは

はじめに、Mayaの操作でどのようなコマンドが実行されているか確認してみます。
実は操作によってはMELコマンドがスクリプトエディタの中で表示されていることが多いです。
コマンドとは、Mayaで実行する処理一つ一つのことをいいます。
このMELコマンドの表示がツールを作るための大きな手掛かりになります。
スクリプトエディタで表示されるコマンドはこちらに詳しく載っていますのでチェックしてみてください
【Maya】表示されないMELコマンドを知る方法:初心者編

リネームコマンドを確認する

はじめにCubeなど簡単なプリミティブをシーンに表示させた状態にしておきます。
スクリプトエディタをMayaの画面右下のボタンから開いてみましょう。
Mayaでは操作を行う度に、スクリプトエディタ上部の枠にヒストリがたまっていくため、
実行されるコマンドが見やすいようにClear Historyボタンを押してヒストリを削除しておきます。

次にアウトライナでCubeを「Test」とリネームしてみると、
rename "pCube1" "Test"; というテキストが表示されます。
これがキューブ名 「pCube1」を「Test」にリネームする処理のMEL言語のコマンドになります。
それではMELからPythonへ変換してみましょう。

MELからPythonへ

MELとPythonのコマンドドキュメントを見比べてみます。
コマンドドキュメントは
各Mayaのバージョンのヘルプのページ(Maya helpと検索すれば出てきます) > テクニカルドキュメントから確認できます
以下からrenameコマンドを見てみます
MELコマンド ドキュメントリンク
Pythonコマンド ドキュメントリンク

コマンドの使い方は概要のところにあります。
MELとPythonはまず以下のような違いがわかります。
・MEL のほうでは -(ハイフン) がある
・Pythonのコマンドでは =(イコール) がある

これはフラグというもので、処理の細かいオプション設定をする場合にコマンド内に記述するものです。
・MELは -フラグ名(ハイフンの後ろにフラグ名を付ける)
・Pythonでは =フラグ名 (イコールの後ろにフラグ名を付ける)
という風にフラグを設定することでオプション処理ができます

先ほどのrenameコマンドではrename "pCube1" "Test";でしたので、フラグはありません。
MELの概要を見ると rename “リネームするオブジェクト名” “リネームテキスト” という風に実行していることが読み取れます。

これをPythonの方で置き換えてみましょう。
Pythonの方のドキュメントでは先ほどのMELとはフラグの記述の順番が異なりますね。
またMELとは違って、引数に「,」(コンマ)が必要であり、またコマンド全体を()で括ってあげる必要があることがわかります。
今回はフラグが必要ありませんので、rename("pCube1","Test")で実行できそうですね

ただしここで注意点として、Pythonコマンドを実行するときは必ず

import maya.cmds as cmds

といった呪文を唱える必要があります。
これはモジュールのインポートといい、mayaのcmdsモジュールをcmdsとして定義してコマンドを使いますよ
ということを宣言してあげなければコマンドを使うことができません。

renameやlsなどのPythonコマンドはMayaのcmdsのモジュールに含まれている処理関数なので、
モジュールの宣言定義をした後に

cmds.rename("pCube1","Test")

という風にコマンドの前にcmdsを書く必要があります。

 

ツールを作ってみよう

検証で”rename”コマンドを使えばリネームできるということがわかりましたね
それでは本格的に仕様に則ったツールを作ってみましょう。

今回は
(1)選択したモデルをすべて取得して(名前を取得して)
(2)任意のプリフィックス + 取得したモデル名 でリネームする

という大きく2段階の処理が必要ですね。
とりあえずtest_というプリフィックスを付けるようにしてみましょう。

lsコマンド

(1)で選択したモデルの名前をすべて取得するにはlsコマンドを使います。
lsコマンドのドキュメントを見ると沢山のフラグがあることが分かります。
このlsコマンドはシーンの中のノードに対して、フラグで指定した要素でフィルタリングをして取得できる処理を行うもので、非常によく使うコマンドになります。
lsコマンド Pythonドキュメント

lsコマンドの使い方についてはこちらの記事にまとめてありますので、要チェックです!
【Maya】Melのlsコマンドの可能性

試しに3つのCubeをつくり、3つのCubeを選択した状態で、
以下のようにスクリプトエディターの下のPythonタブに打ち込み、
ctrl+A → ctrl+Enterで全選択してから実行してみます


import maya.cmds as cmds
selected_obj_list = cmds.ls(selection=True, transforms=True)
print(selected_obj_list)

上のスクリプトは選択したモデルに対し、変数selected_obj_listにlsコマンドで取得したモデルリストとして格納する処理になります。
そのため、実行した後、['pCube1', 'pCube2', 'pCube3']と、選択したモデル名のリストが取得できたと思います。
変数というのはザックリと説明すると、x=1のようにxに1として設定したよ!というものです。
変数名が同じものであればその記述以降の処理に使いまわせます

この処理ではlsコマンドのselection、transformsの2つのフラグを有効にしたため、
「選択したノードで」「タイプはtransformノード」に合致したモデル名をリストとして受け取りました。
これで選択したモデルリストを取得できました!

複数のモデルを繰り返しリネームするには

(2)では、(1)で取得したすべてのモデルに対して、リネームを一つ一つ実行する必要があります。
Pythonにおいて一つ一つ繰り返して処理を行うにはfor文処理を使います。
cmds.rename(“リネームしたモデル名”,”リネームテキスト”)とコマンドを実行することでリネームできるので、
prefix = “test_”とひとまずプリフィックスを仮で設定して、for文でリネーム処理を実行しましょう

リネームするオブジェクトを選択し、以下のようにスクリプトエディターのPythonタブに打ち込み
ctrl+A → ctrl+Enterで実行してみます


import maya.cmds as cmds

selected_obj_list = cmds.ls(selection=True, transforms=True)

prefix = "test_"

for obj_name in selected_obj_list:
    rename_obj_name = prefix + obj_name
    cmds.rename(obj_name, rename_obj_name)

実行後アウトライナでモデルの名前を確認するとリネームできたことが確認できました!
試しに1回ctrl+ZでUndoを行い、 prefix = “test_” を書き換えてみると
任意のプリフィックスで設定できることができます。

 

ツールをインポートして実行しよう

今回はMayaのスクリプトエディタを使ってツールを作りましたが、
大体は作りやすさの面でVSCodeなどの外部のエディタを使って.pyファイルを作成してからMayaにimportすることが多いです。
スクリプトエディタで作成した.pyファイルを一度出力し、importしてMayaで実行する一連の流れをやってみましょう

初めに先ほど作成したスクリプトを ctrl+A ですべて選択し ctrl+S で.pyファイルを保存します
保存先は、Maya側が読み込めるパスの場所でなければなりません。
今回はデフォルトでパス設定されている
ドキュメント > maya > scriptsの中に rename_tool.pyとして保存します

それでは保存した場所からツールを呼び出して実行してみます。スクリプトエディターのPythonタブに以下のように記入し、


import rename_tool
import importlib
importlib.reload(rename_tool)

rename_tool

ctrl+A で全選択し、マウスの中クリックドラッグでシェルフまでスライドして登録をしておきます
シェルフにツールを登録しておくと、そのツールのアイコンをクリックするだけでツールの実行を行うことができます

以上の設定が終わったらツールをクリックして実行してみます。
スクリプトエディターの上部にErrorが出なければ成功です!
エラーが出てしまったらrename_tool.pyの保存場所と大文字小文字が打ち間違えてないかチェックをしてください

上記のimport~のスクリプトは、Mayaで読み込めるパスに存在するrename_toolを読み込み、再リロードしてから実行するという処理です。
Mayaでは一度importすると保存内容が更新されないためimportlibのリロード処理が必要です。
最後のrename_toolの記述でrename_tool.pyツールを実行をしていることになります。
ただし、現在までに作成したコードでは、Pythonでdefと書く関数に入れて実行してないのでこれはむき出しの処理になっています。
むき出しの処理ではimportをした時点で勝手に実行される恐れもあり、不具合の原因になりかねません。
これをmainと名付けた関数の中に収めてからmain関数から実行できるように以下のように書き換えてみましょう


import maya.cmds as cmds

def main():
    selected_obj_list = cmds.ls(selection=True, transforms=True)

    prefix = "test_"

    for obj_name in selected_obj_list:
        rename_obj_name = prefix + obj_name
        cmds.rename(obj_name, rename_obj_name)

そして、先ほど登録したシェルフツールの上で
右クリック→Edit でShelfエディターを開き、main関数から実行できるように書き換えます。

Commandのタブにおいて先ほど書いた最後の行の
rename_tool → rename_tool.main()と書き換えることでrename_tool.pyのmain関数を呼び出して実行することができました

Tips

Mayaが読み込めるパスの確認方法は以下になります


import sys
print(sys.path)

今回はデフォルトのパスを選択しましたが、
Mayaの起動batなどでPYTHONPATHの環境変数にパスを設定することで
新たに読み込むパスを追加することができます。興味があればやってみてください!

 

ツールを使いやすく修正してみよう

はじめてツールを作ってみた方には長い道のりだったと思います…が!もうちょっとだけ続くんじゃ

現状のツールでは

prefix = "test_"

のように定義したプリフィックスでリネームができる仕様ですが、
プリフィックスを変えたい場合は毎回rename_tool.pyを開いて書き直して…としなければならない状態です。

ここで改良の一例ではありますが、以下の手順に沿って
(1)プリフィックスを記入するためのウィンドウテキストボックスを表示してユーザーに記入してもらう
(2)Applyボタンを押すと記入したテキストをプリフィックスと設定しリネーム処理を行う
…という風に実行するUI構成に修正しましょう
PysideでUIを作ってもいいのですが、今回は長くなりそうなので、MayaのコマンドでUIを作ります

MayaコマンドでUIを作ろう

以下UI部分の作り方の紹介です。
以下は処理の流れに紹介していますので、処理の書き方は最後の完成スクリプトを参考にしてください。

(1)まずはウィンドウを作成し、レイアウトを設定します。
すでにウィンドウが出ている場合は沢山表示されるので常に1つだけ出てくるようにします


# 既にrename_toolを開いている場合はウィンドウを閉じます
if cmds.window("rename_tool", q=True, exists=True):
    cmds.deleteUI("rename_tool")

# Windowを開きます
window = cmds.window(title="rename_tool", widthHeight=[310, 80])
cmds.columnLayout(adjustableColumn=True, margins=10)

(2)ユーザー側にUIで何してほしいかを知らせるためにもcmds.textで説明書きの一行を入れます。
そして、prefixを入力するための、textFieldButtonGrpコマンドでテキストボックスとボタンがセットになったUIを入れ込みます。

ボタンを押したときに実行するという操作は、
cmds.textFieldButtonGrpのbuttonCommandフラグに、ボタンを押したときに実行する処理を設定します。
ボタンを押したときにこれまでに作ったリネーム処理をしてほしいので、リネーム用関数rename_objにリネーム処理をまとめて接続します。


cmds.text("リネームのプリフィックスを記入してください", align="left", height=14)
cmds.textFieldButtonGrp("prefix_text_grp", buttonLabel="Apply",
                        buttonCommand=functools.partial(rename_obj))

ここではfunctools.partialというものを使ってbuttonCommandで実行する処理を設定しています。
このように書くと、引数が必要な関数処理に引数を渡すことができてとても便利です

functoolsについてはこちらの「functools.partial ってなに!?」という部分に載っていますので、チェックしてみてください!
スクリプト練習に最適! カスタムファイルブラウザで仕事効率化!

(3)入力したprefixテキストを取得するには以下のように取得できます

cmds.textFieldButtonGrp("prefix_text_grp", q=True, text=True)

フラグqというのは参照(=現在の入力値など、値をGetする)フラグであり、
q=Trueとコマンド内に書くことで参照可能になります。
“prefix_text_grp”は(2)で作成したtextFieldButtonGrpコマンドで作成した実体名を指定しています。

以下完成のスクリプトです


import maya.cmds as cmds
import functools

def main():
    # 既にrename_toolを開いている場合はウィンドウを閉じます
    if cmds.window("rename_tool", q=True, exists=True):
        cmds.deleteUI("rename_tool")

    # Windowを開きます
    window = cmds.window(title="rename_tool", widthHeight=[310, 80])
    cmds.columnLayout(adjustableColumn=True, margins=10)
    cmds.text("リネームのプリフィックスを記入してください", align="left", height=14)
    cmds.textFieldButtonGrp("prefix_text_grp", buttonLabel="Apply",
                            buttonCommand=functools.partial(rename_obj))
    cmds.showWindow(window)


def rename_obj():
    # 選択したモデルすべてに テキストボックスに記入したprefixでリネームします
    selected_obj_list = cmds.ls(selection=True, transforms=True)
    prefix = cmds.textFieldButtonGrp("prefix_text_grp", q=True, text=True)

    for obj_name in selected_obj_list:
        rename_obj_name = prefix + obj_name
        cmds.rename(obj_name, rename_obj_name)

これでやっと完成です!!!ツールを実行するとウィンドウが出てきたでしょうか!
prefixを入力してApplyボタンを押したらリネームできたことが確認できたと思います。
ながいながい道のりでしたが、今回ツールの作成の一連の流れについて掴めましたら幸いです。お疲れさまでした!

tanaka rika

新卒からTAになりました。MayaのツールとHoudini関連の仕事をしています。
フェレットと暮らして10幾年。動物かわいいフェレットかわいい。

関連記事

  1. 【Maya】ローポリキャラモデリングのコツ

    2020-11-24

  2. 【Maya】MELでシェルフアイコンをクリックで変更してみた

    2019-06-11

  3. 【Maya】表示されないMELコマンドを知る方法:追記編

    2020-08-18

  4. 【Maya】表示されないMELコマンドを知る方法:初心者編

    2019-11-26

スキルレーダーチャート

テクニカルアーティスト専用
スキルレーダーチャート
どなたでも無料でご利用いただけます。

ABOUT

TECH COYOTE​

テクニカルアーティストの為のまとめサイトです。​
本サイトでは、ツール開発、業務効率化等について情報発信をしていきます。

COYOTE 3DCG STUDIO

C&R Creative Studios

RECENT TWEET

ページ上部へ戻る