チュートリアル / 読んで触ってよくわかる!Mayaを使いこなす為のAtoZ
第94回:Time Slider Bookmarkをスクリプトで操作してみよう!
- Maya
- ゲーム
- コラム
- スクリプト・API
- チュートリアル
- 上級者
- 中級者
ゲームのアニメーションを作る時に「100フレームから160フレームは待機のループモーション」と決めてアニメーションをつけたりします。そのフレーム間のアニメーションをゲームに書き出すわけですが「どのフレームが何のモーション」というのをどのように管理していますか?
昔はツールを自作していました。ツールがないなら紙とかに書いておくなど、なかなかデジタルとアナログが融合した感じで作業していました。1ヶ月後にシーンを開いて編集し直すときなど、フレーム数を間違えて書き出して、プログラマに怒られるというのを見かけたような気も…。
今はGame Exporterプラグインがあります。FBXのアニメーション書き出しに対応しており、フレーム間とモーションの名前を管理できます。「gameFbxExporter.mll」プラグインを読んでから「File > Game Exporter」を選ぶと、次のようなウインドウが表示されます。
Animation Clipsタブで、書き出したいアニメーションの名前とフレーム間を指定できます。
機能は良いのですがこの「○フレームから△フレームまで」という設定はTime Sliderには表示されません。アニメーション作業中に視覚的に確認できないのがちょっと不便です。
Maya 2020から利用できるTime Sliderのブックマークは、Time Sliderで視覚的にアニメーションの範囲を確認できます。
これをスクリプトで編集したり設定を取ったりできれば、Game Exporterの代わりのエクスポーターとしても利用できそうです。
ところがMELコマンドのヘルプで「bookmark」とか検索しても、Time Slider Bookmarkを操作できそうなものは見つかりません。ではどうやって見つければよいのか…。
工夫すれば使用したいどんな機能のコマンドでもすぐに見つけられます!
今回はどのようにしてTime Slider Bookmarkのコマンドを見つけ出すかという、始めの始めから順番に見ていきましょう!
MELコマンドを調べてみよう!
探している機能名のコマンドがヘルプのMELコマンドドキュメントで見つからない場合、とりあえずGUIから機能を実行してScript Editorに出力される内容を確認します。
Time Sliderを右クリックして、メニューから「Time Slider Bookmarks > Create」を選びます。
フローティングのウインドウが表示されますので、名前を「Test」として実行します。
普通はこれで何かしらコマンドが実行されて、Script Editorに履歴として表示されます。が、Script Editorを見ても何も表示されません。
こういうこと、ありますね。
Undoするとなにか出ることがあるので、Undoしてみます。
微妙ですね…。ブックマークに関わる内容ではなさそうです。
次に試すのは、Script Editorのメニューで「History > Echo All Commands」をオンにして、なるべく多くのメッセージを出力するようにします。
それで改めてブックマークのCreateボタンを押すと、出力はこんな感じになります。(Mayaの状況によって結果は変わります。)
色々出てきたので、有用なものがないか確認します。
実行されている行ごとに頭の中に浮かんだコメントを書くとこんな感じです。
$tmpVar=$gPlayBackSlider; // スライダーのなにか?今は意味ない。
setFilterScript "initialShadingGroup"; // シェーダの名前なので、関係ない。
setFilterScript "initialParticleSE"; // パーティクルのシェーダの名前なので、関係ない。
setFilterScript "defaultLightSet"; // ライトセットの名前なので、関係ない。
setFilterScript "defaultObjectSet"; // オブジェクトセットの名前なので、関係ない。
autoUpdateAttrEd; // AttrEdはAttribute Editorの略。Attribute Editorの更新っぽい。
import maya.internal.ufeSupport.utils as ufeUtils; ufeUtils.isPathStringValidObject('')
// 突然Pythonが。ufeはUFE(Universal Front End)というOutlinerの仕組み。
CBselectionChanged; // CBはCallbackの略だろうから、選択の変更でなにか呼んでるっぽい。
import maya.internal.ufeSupport.utils as ufeUtils; ufeUtils.hasNonMayaSelectedItems()
// またPython。UFEと書いてあるので関係なさそう。
updateAnimLayerEditor("AnimLayerTab"); // Animation Layer Editorの更新っぽい。
statusLineUpdateInputField; // Status Lineの入力フィールドが更新されたっぽい。
if (!`exists polyNormalSizeMenuUpdate`) {eval "source buildDisplayMenu";} polyNormalSizeMenuUpdate;
// polyNormal~なので、メッシュの法線関係の何か。関係ない。
dR_updateCounter; // なにかカウントしている。関係ない。
dR_updateCommandPanel; // コマンドパネルを更新。なんか知らないけど関係ない。
timeField -edit -value `currentTime -query` TimeSlider|MainTimeSliderLayout|formLayout8|timeField1;
// 現在時間が変更されたようだが、関係なさそう。
…何も関係ある物がないですね。なかなか手ごわいです。
こういうときは「GUIに表示されている名前」をもとに辿ります。
GUIの表示名をもとにコマンドを辿る
使いたい機能のメニューやウインドウ、ツールのオプションなど、何かしらGUIで文字が表示される場合、その文字列を検索して、どのスクリプトがGUIを作っているか調べます。
日本語UIだと辿りにくいので、英語UIのMayaでGUIに表示される文字列を確認しながら進めます。
ブックマーク作成のウインドウのタイトルには「Create bookmark」と書かれています。
なるべくその機能特有の名前の方が見つけやすいです。
「Create bookmark」は、どこにでも出てきそうな雰囲気があります。ビューにもNode Editorにもブックマークがありますので。
が、専用のGUIで作成するというのは特徴的なので、「Create bookmark」ですぐに見つかる見込みはあります。
次にどこを検索するかですが、Mayaのインストール先である「C:\Program Files\Autodesk\Maya2023」の中を検索します。
テキスト内検索が必要ですので、ファイル内検索が可能なツールを使います。(Visual Studio Codeなど)
ちなみにMaya2023\scriptsフォルダ内にMELスクリプトの大半が入っていますので、普通はこのフォルダ内だけ検索すれば十分です。
ところが最近はPythonでGUIを作ることもあるので、Maya2023\Pythonフォルダ内も検索しないと、探している物が見つからないことがあります。
では「Create bookmark」で「C:\Program Files\Autodesk\Maya2023」の中を検索します。
次のようにいくつかファイル結果が出てきます。nodeEditorBookmarks_res.pyにも見つかりますし、bookmarkButton.pyというのも見つかります。
見つかった対象のファイル数は多くないので一つずつ見ていってもいいですが、bookmarkManager_res.pyという名前のファイルがいかにも「偉そう」なので、これが怪しいです。
(MayaStringsというファイルはresourcesフォルダ内にあり、言語対応用のファイルです。)
「bookmarkManager_res.py」というファイル名に含まれている「_res」と言うのは、GUI用の文字列をまとめたファイルということです。
「_res」を取り除いたファイルが本体として存在するはずですので、「bookmarkManager.py」というファイルがないか探します。
ファイルが有れば「kBookmarkCreateBookmark」という名前で「Create bookmark」という文字列が使用されているはずです。
次の場所でbookmarkManager.pyが見つかります。
「C:\Program Files\Autodesk\Maya2023\Python\Lib\site-packages\maya\plugin\timeSliderBookmark\bookmarkManager.py」
中を「kBookmarkCreateBookmark」で検索すると「CreateBookmarkDialog」というクラス内で使われていることがわかります。
self.setWindowTitleという関数の引数ですし、クラス名はCreateBookmarkDialogですし、ほぼ間違いなくここでCreate bookmarkのウインドウを作っています。
こんな感じで、使いたい機能に関係した部分が徐々に判明します。
このPythonファイルは何?
bookmarkManager.pyが入っているフォルダの名前をよく見てみると「timeSliderBookmark」と書いてあります。
中に色々とPythonファイルが含まれています。名前からして、ブックマークをなにかしてくれそうです。
このフォルダはTime Sliderのブックマークをいじるためのモジュールです!
最近「MELにはコマンドがないけれどPythonモジュールがある」という機能がちょくちょくあります。
他にも「C:\Program Files\Autodesk\Maya2023\Python\Lib\site-packages\maya\internal\nodes」の中を見ると、proximityPinやproximityWrapがあったりします。これらはProximity Pin/Wrapを作成・編集するためのものです。
Maya2023/scriptsフォルダ内にAttribute Editorのテンプレートがなかったり、GUIを作るスクリプトがなかったりすると、Pythonのモジュールとして用意されていることもあるので「Python\Lib\site-packages\maya」内をチェックしてみて下さい。
Time Slider Bookmarkを作るコマンドはどこ?
Create bookmarkウインドウでブックマークを作ると、シーンにtimeSliderBookmark1というノードが作られます。
Outlinerで「Display > DAG Objects Only」をオフにしてみると、こんな風にノードが現れます。
これでどうやってTime Sliderに描画されているのでしょうか?どう管理されているか知らないとスクリプトを組めないので、もう少し詳しく調べていきます。
Time Slider BookmarkのGUIは、Time Sliderを右クリックして出てくる「Time Slider Bookmarks > Bookmark Manager」を選ぶと出てきます。
真ん中あたりにシーン内のブックマークがリストアップされて出てきます。どうやってブックマークを選んでいるか、Bookmark Managerウインドウを作成しているスクリプトから調べていきましょう。
で、明らかに、名前からしてbookmarkManager.pyが怪しいですね。この中でウインドウを作っている確率が高いです。
もう一度bookmarkManager_res.py内でBookmark Managerウインドウのタイトル名を検索すると、次の部分で見つかります。
kBookmarkManagerTitleという文字列で指定されているようなので、bookmarkManager.py内で検索します。
するとBookmarkManagerクラス内で使用されていることがわかります。
ではウインドウに表示されているブックマークはどこで表示しているか探してみます。
このself.setWindowTtitleのあとに出てくるはずです。コードは次のようになっています。
TopBarBookmarkManager()は、直後にSeparator()というのが追加されているので、ウインドウの上部に出てくるアイコン達の行だと思われます。
QScrollArea()というのはQtでスクロール可能な場所を作ります。ブックマークが複数あるとスクロールバーが出るので、ここっぽいです。
でもそのあとの5行程度見た感じでは、CreateとかAddとかいった記述がないので、スクロールエリアの場所だけ作っているようです。
その下のコードに行くと、BookmarkCreateLine()というのがあります。これはブックマークを作成用なので、ウインドウの下部に出てくる一行のはずです。
次にself.updateUI()が出てきます。空のレイアウトだけ作っておいて、後で「UIの更新」として中身を埋めていくパターンもあるので、このupdateUIが怪しいです。
同じファイル内でupdateUI関数を探すと、次の関数が見つかります。
「Fill up the bookmark manager from the scene」と書いてあるので、これで各ブックマークの表示を作っているっぽいですね。
で、コードを見てみるとはじめにこれが出てきます。
tsbs = cmds.ls(type="timeSliderBookmark")
つまりシーン内のtimeSliderBookmarkノードをlsコマンドでリストアップして、それをもとにGUIを作成しているようです。
試しに createNode timeSliderBookmark; と書いて実行すると、Bookmark Managerに表示されます。
timeSliderBookmarkノードのアトリビュートを変えると、Bookmark Managerも更新されます。
アトリビュートを変えると、Time Sliderのブックマーク表示も変わります。
この結果からすると、Bookmark Managerになにか登録しておくようなことは不要で、シーンにノードを作れば自動的に見つけてくれるようです。Time Slider上の描画も自動的に行われるようです。(Bookmark Managerが描画しているのか、Time Sliderが描画しているのかはわかりませんが。)
とりあえず、単に「timeSliderBookmarkタイプのノードをcreateNodeで作って、アトリビュートをsetAttr/getAttr」すればツールを作れそうです!
まとめ
使いたい機能がどうやってスクリプトで動いているか、Mayaのコード内を泳いでいく方法を見てきました。
結果的にtimeSliderBookmarkノードを作るだけでOK!とわかりましたが、仕組みを紐解くことで確実に、安全に扱えるようになっていることが重要ですね。
と、実はここまでは前置きでして、本題は「なぜわざわざPythonモジュールが用意されているか?」というところにあります。
次回はtimeSliderBookmarkモジュールを使って、より賢く簡単にTime Slider Bookmarkを扱う方法を見ていきます。