my funeral week

少しでも日々の生活に変化を。

MayaScripts_FrameStepPlus:フレーム送り置き換え

こんにちわ。 最近えらく寒くなりましたね。

・・・忙しいんで前置きはいいですわ。

今回は小スクリプトの紹介になります。


FrameStepPlus

Maya標準のフレーム送り機能あるじゃないですか。1フレームづつ送ることができるアレです。 アレでも全然問題ないんですけど、Mayaのバージョンによってフレーム端まで送った時の挙動が異なる ように感じるのですけど・・・そんなことないですか?

例えば、Maya2018でフレーム送りをすると・・・

f:id:garysfirearms108:20211219005209j:plain

こんな感じにタイムスライダーがアニメーションの再生範囲外まで行ってしまう。

f:id:garysfirearms108:20211219005219j:plain

ところがMaya2020だと、アニメーションの再生範囲の端まで行くと、反対側の端までスライダーが飛ぶようになってたり、Maya2018でもUI上のPlaybackControlのボタンをクリックしてフレーム送りをするとMaya2020と同じ挙動で動いたりと・・・。

自分が良く知らないだけかとも 強く思います が、仕事の都合で使用するMayaのバージョンは行ったり来たりと頻繁に切り替える必要があり、その都度調べるのも面倒なので例によってスクリプトで解決することにしました。


コード

# encoding=utf8
# -*- coding:utf-8 -*-

import pymel.core as pm

NAME = "FrameStepPlus"
VERSION = "1.0"

print "-----import", NAME + VERSION, "-----"

MODE = ["cycle", "continuous", "jump"]
currentMode = MODE[0]

def __stepTo (vectorInt):
    current = pm.currentTime()
    pm.currentTime(current + vectorInt)

def __jumpTo (vectorStr):
    time = pm.findKeyframe(ts = True, w = vectorStr)
    pm.currentTime(time)

def __stepToCycleFrame (vectorInt = 1):
    minTime = pm.playbackOptions(q = True, min = True)
    maxTime = pm.playbackOptions(q = True, max = True)
    current = pm.currentTime()
    
    if current <= minTime and vectorInt < 0:
        pm.currentTime(maxTime)
        return
        
    if current >= maxTime and vectorInt > 0:
        pm.currentTime(minTime)
        return
    
    __stepTo(vectorInt)

def stepToNextFrame ():
    """次のフレームに送る"""
    if currentMode == MODE[0]:
        __stepToCycleFrame(1)
        return
    if currentMode == MODE[1]:
        __stepTo(1)
        return
    __jumpTo("next")
    
def stepToPrevFrame ():
    """前のフレームに送る"""
    if currentMode == MODE[0]:
        __stepToCycleFrame(-1)
        return
    if currentMode == MODE[1]:
        __stepTo(-1)
        return
    __jumpTo("previous") 

def switchMode ():
    """フレーム送りタイプを切り替える"""
    global currentMode
    
    index = MODE.index(currentMode)
    index = index + 1
    if index >= len(MODE):
        index = 0
    currentMode = MODE[index]
    
    line = "-----------------------"
    pm.headsUpMessage(line+"FrameStepPlus.switchMode : "+currentMode+line)


上記のコードを「FrameStepPlus」という名前のPythonファイルに保存し、以下の場所に配置。

C:\Users\"ユーザー名"\Documents\maya\scripts


各機能を実行するには以下のコードを入力してください。

次のフレームに送る

import FrameStepPlus
FrameStepPlus.stepToNextFrame()

前のフレームに送る

import FrameStepPlus
FrameStepPlus.stepToPrevFrame()

基本的には上記のコードを任意のホットキーに登録して利用することを想定しています。
過去にXSIを使っていた経験から、なんとなくフレーム送り機能のホットキーは矢印である方が嬉しいので、自分は「左右の矢印キー」にそれぞれ登録しています。

動作の挙動としては再生範囲の前後端で折り返すようにフレーム送りを行うものになっていますが、どのようにフレームを送るのかタイプを切り替えることが出来ます。


フレーム送りタイプを切り替える

import FrameStepPlus
FrameStepPlus.switchMode()

このコードを実行すると、以下の3タイプのモードで切り替えます。

  • cycle:再生範囲の端で折り返す。
  • continuous:再生範囲の端で折り返さない。
  • jump:次または前のキーフレームまで飛ぶ

好みに併せて、これも適当なホットキーに登録するといいかもしれません。

つっても最後の「jump」は既存のホットキーにあるものですけども。



以上。今回はこんな感じです。
なんともまぁ標準の機能にありそうなものをわざわざスクリプトに置き換えているだけ感が漂っていますが、とにかくソフトのバージョンが違っても必ずこちらが想定している動作をしてくれる保障がある方が精神的に安心なので、これでいいんです。これで。