チュートリアル / 読んで触ってよくわかる!Mayaを使いこなす為のAtoZ
第95回:Time Slider Bookmarkをスクリプトで操作してみよう!その2
- Maya
- ゲーム
- コラム
- スクリプト・API
- チュートリアル
- 上級者
- 中級者
前回はどのスクリプトでTime Slider Bookmarkが作成されているか探す方法をご紹介しました。実際に私が探したときの手順をそのままのライブ感でご紹介したので、回り道もありましたが、泥臭いパターンだとこうなるというのが伝わりましたでしょうか…。
Pythonモジュールが関わるとああなりがちでして、MELスクリプトで作られていれば同じ方法でももっと簡単にスクリプトを見つけられます。
今回は見つけたスクリプトを駆使してTime Slider Bookmarkを自由に操作していきましょう!
Time Slider Bookmarkを操作するオススメの方法
前回わかったことをまとめると、こんな感じです。
・シーン内にあるtimeSliderBookmarkノードを自動的に見つけて、エディタやTime Sliderにブックマークを表示してくれる。
・「C:\Program Files\Autodesk\Maya2023\Python\Lib\site-packages\maya\plugin\timeSliderBookmark\bookmarkManager.py」がブックマークマネージャ。
・「C:\Program Files\Autodesk\Maya2023\Python\Lib\site-packages\maya\plugin\timeSliderBookmark」はブックマークに関するPythonモジュールらしい。
しれっとcreateNodeコマンドで次のようにノードを作れば、ブックマークを作ることが出来ます。
createNode timeSliderBookmark;
アトリビュートを変更すれば自動的にUIへ反映されるので、setAttrをすればよいです。
だがしかし、なぜにモジュールが用意されているか、ということです。
モジュールを使ったほうが色々と便利なことがあるからこそ用意されているのでしょう。というわけでモジュールにどういう機能があるか見てみましょう。
timeSliderBookmark.pyという一番さっぱりした名前のファイルを開いて、関数を見てみましょう。便利そうな名前の関数がいくつかあるようです。
createBookmarkという関数があります。ブックマークを作成するのにいいかもしれません。
def createBookmark(name=None, start=None, stop=None, color=None):
具体的に中身を見てみると次のようなコードになっています。
def createBookmark(name=None, start=None, stop=None, color=None):
'''createBookmark create a bookmark from time range selections'''
selection = cmds.ls(sl=True)
cmds.pluginInfo("timeSliderBookmark", edit=True, writeRequires=True)
bm = cmds.createNode("timeSliderBookmark")
updateBookmark(bm,start=start,stop=stop)
if name != None:
cmds.setAttr(bm + ".name", name, type="string")
if color == None:
color = [x/255.0 for x in pickColor()]
cmds.setAttr(bm + ".color", *color)
priority = getNextPriority()
cmds.setAttr(bm + ".priority", priority)
cmds.select(selection, replace=True)
cmds.currentTime(stop)
return bm
createNodeでtimeSliderBookmarkを作成しています。
それ以外にも色々と前準備や後準備があるようです。
この関数を使うほうがcreateNodeで作るより良さそうです。今後のバージョンで何かしらブックマークに機能が追加、変更されるかもしれませんし、この関数を使っておけば間違いなさそうです。
createBookmark関数でブックマークを作ってみましょう。
timeSliderBookmark.mllプラグインがロードされていなければ、先にロードしておきます。
次のスクリプトを実行すると、自動的にプラグインをロードして、ブックマークを作成します。
import maya.cmds as cmds
import maya.plugin.timeSliderBookmark.timeSliderBookmark as timeSliderBookmark
if not cmds.pluginInfo('timeSliderBookmark', q=True, loaded=True):
cmds.loadPlugin('timeSliderBookmark')
timeSliderBookmark.createBookmark(name='testBookmark', start=10, stop=60, color=(0.8, 0.3, 0.7))
実行すると次のように紫色のブックマークが10~60フレームの範囲に作られます。
createNodeよりも簡単です!
現在時間にあるブックマークを取る
現在時間にあるブックマークを取りたいのですが、まともにやろうとすると、すべてのブックマークの時間の範囲を確認することになります。
こういうちょっとややこしい操作は、関数で対応してそうな予感がしますね。モジュールを見てみましょう。
timeSliderBookmark.pyの中には沢山の関数があるので、現在時間に関わる処理を探してみましょう。
「currentTime」で検索していくとgetBookmarkAtTime(time)という関数が見つかります。そのものズバリな名前の関数です!
def getBookmarkAtTime(time):
'''return the bookmark that is considered on top at given time'''
bms = getAllBookmarks()
currentTime = time
currents = [bm for bm in bms if isInBookmarkRange(bm, currentTime)]
return getHighestPriorityBookmark(currents)
早速実行してみます。
timeSliderBookmark.getBookmarkAtTime(20)
# Result: timeSliderBookmark1
先程スクリプトで作成したブックマークは10~60フレームの範囲なので、getBookmarkAtTimeで20フレームを指定すると正しくブックマークが得られました。素晴らしい!
単純な値を取る場合は、直接setAttr, getAttrすると簡単なときもありますし、ちょっと複雑な操作はモジュールを使うと便利だったりしますので、このあたりはうまく使い分けてみてください。
ブックマークを自動で割り振る機能を作る
ここでちょっと実用的なものを作ってみましょう。
新しくキャラクタのアニメーションを作成する時に、ゲームでは最低限必要なアニメーションがあります。そういった決め打ちのアニメーションの割り振りを自動で作る機能を作ってみましょう。
実行すると「1~120フレームは待機ループ」「121~240は歩き」「241~360は歩きから待機ループへのつなぎ」という感じでブックマークを作ります。
折角なのでcreateBookmark関数を使ってみましょう。
プラグインの読み込みも含め、完全なコードでもこの程度で済みます。
import maya.cmds as cmds
import maya.plugin.timeSliderBookmark.timeSliderBookmark as timeSliderBookmark
if not cmds.pluginInfo('timeSliderBookmark', q=True, loaded=True):
cmds.loadPlugin('timeSliderBookmark')
timeSliderBookmark.createBookmark(name='waitLoop', start=1, stop=120, color=(0.3, 0.8, 0.4))
timeSliderBookmark.createBookmark(name='walk', start=121, stop=240, color=(0.3, 0.6, 1.0))
timeSliderBookmark.createBookmark(name='walkToWait', start=241, stop=360, color=(1.0, 0.5, 0.8))
結果は次の画像の通り、一度にブックマークが作られます。
これなら毎回同じ作業を間違いなく行えるので便利です!
ブックマークをもとにファイルを書き出す
ブックマークを更に活用するために、ブックマークの時間の範囲や名前をもとにファイルを書き出してみましょう。
timeSliderBookmarkノードをlsコマンドでリストアップする方法がスタンダードな方法です。
が、モジュールになにか便利なものがないかと見てみると、getAllBookmarksという関数があることに気づきます。
次のように実行すると、時間順でブックマークが配列として返ってきます。
timeSliderBookmark.getAllBookmarks()
# Result: ['timeSliderBookmark1', 'timeSliderBookmark2', 'timeSliderBookmark3']
時間順というのがいいですね。
今度はノード名から時間の範囲を調べます。
timeSliderBookmark1を選択してアトリビュートエディタを見てみると、timeRangeStartとtimeRangeStopというアトリビュートが範囲となるようです。
timeSliderBookmark.py内でtimeRangeという文字列を検索すると、いくつかヒットします。
でもこれと言って便利そうなものはないので、この値は直接取ったほうが良さそうです。
FBXに書き出したいので、初めにfbxmaya.mllがロードされているか確認して、ロードされてなければロードします。
次に、シーン内のブックマークをすべて取得し、順番にFBXに書き出します。
FBXに書き出すときのコマンドが少々独特なので戸惑いますが、概ね次のようなコードを実行すれば、ブックマークごとにFBXを書き出せます。
ここではoutputDirに書き出し先のフォルダを指定していますので、皆さんの環境に合わせて設定してください。フォルダを作っておくことも忘れずに!
import maya.cmds as cmds
import maya.plugin.timeSliderBookmark.timeSliderBookmark as timeSliderBookmark
if not cmds.pluginInfo('fbxmaya', q=True, loaded=True):
cmds.loadPlugin('fbxmaya')
outputDir = r'D:/temp/'
bookmarks = timeSliderBookmark.getAllBookmarks()
for bookmark in bookmarks:
startTime = cmds.getAttr(bookmark+'.timeRangeStart')
endTime = cmds.getAttr(bookmark+'.timeRangeStop')
print (bookmark, startTime, endTime)
cmds.FBXPushSettings() # 今の設定を保存。
cmds.FBXLoadMBExportPresetFile() # デフォルトの設定を読み込み。
# テイクとして名前と範囲を設定。(引数がわかりにくいですが・・・)
cmds.FBXExportSplitAnimationIntoTakes('-c') # clear
cmds.FBXExportSplitAnimationIntoTakes('-v', bookmark, startTime, endTime)
filePath = outputDir + bookmark
cmds.FBXExport('-f', filePath) # 保存します。
print (bookmark, filePath)
cmds.FBXPopSettings() # 設定を戻す。
結果は次のようになります。
シーン名+ブックマーク名のほうがいいかな、など改良したいところが出てきたら、ぜひ色々とチャレンジしてみてください。
まとめ
MayaにPythonが採用されてからずいぶん経ちます。複雑なUIはPythonで実装されていることも多く、年々mayaモジュールフォルダ内にモジュールが増えています。
便利な機能もあったりするので、たまに中を見てみて面白いものを発掘すると楽しいですよ。
今回ご紹介したTime Slider Bookmarkは取っ掛かりが難しい類のものですけれど、コードの書き方がわかれば実に簡単に「使えるツール」が作れますので、ぜひみなさんもブックマーク周りでツールを作ってみてください。