# -*-coding:utf-8 -*-
from maya import cmds
def tween(percentage, obj=None, attrs=None, selection=True):
"""
用于根据给定百分比k帧的函数
:param percentage: 需要k的值占两帧之差比值的多少
:param obj: 需要k帧的物体名字
:param attrs: 需要k的属性
:param selection: 是否执行函数
:return:
"""
# 如果没有给定物体也不执行函数的话,弹出值错误警告
if not obj and not selection:
raise ValueError("No object given to tween")
# 如果没有物体,则默认为选择的第一个物体
if not obj:
obj = cmds.ls(selection=True)[0]
# 如果没有给定属性,则设置属性为该物体所有可k属性
if not attrs:
attrs = cmds.listAttr(obj, keyable=True)
# 获取现在在第几帧
currentTime = cmds.currentTime(query=True)
for attr in attrs:
# 获取该属性的全名
attrFullName="%s.%s" %(obj, attr)
# 获取该属性所有已经k过的帧
keyframes = cmds.keyframe(attrFullName, query=True)
# 如果该属性无关键帧,则跳过该属性
if not keyframes:
continue
previousKeyframes = []
# 获取现在帧的前面关键帧
for frame in keyframes:
if frame < currentTime:
previousKeyframes.append(frame)
# 获取现在帧后面的关键帧(简写)
laterKeyframes = [frame for frame in keyframes if frame > currentTime]
# 如果该属性现在帧的前面或者后面没有k帧,则跳过该属性
if not previousKeyframes or not laterKeyframes:
continue
# 获取现在帧的前面一帧关键帧
if previousKeyframes:
previousKeyframe = max(previousKeyframes)
# 获取现在帧的后面一帧关键帧
if laterKeyframes:
nextKeyframe = min(laterKeyframes)
# 获取前一帧关键帧的值
previousValue = cmds.getAttr(attrFullName, time=previousKeyframe)
# 获取后一帧关键帧的值
nextValue = cmds.getAttr(attrFullName, time=nextKeyframe)
# 计算现在关键帧的值
difference = nextValue - previousValue
weightDifference = difference * percentage/100
currentValue = previousValue + weightDifference
# 设置现在关键帧
cmds.setKeyframe(attrFullName, time=currentTime, value=currentValue)
# 一个窗口类
class TweenWindow(object):
# 给窗口一个标志
windowName = "TweenWindow"
def show(self):
"""
用于显示窗口的函数
:return:
"""
# 判断窗口是否已经存在,如果存在就删除掉旧的窗口
if cmds.window(self.windowName, query=True, exists=True):
cmds.deleteUI(self.windowName)
# 新建一个窗口
cmds.window(self.windowName)
self.buildUI()
# 显示窗口
cmds.showWindow()
def buildUI(self):
"""
用cmds建立UI的函数
:return:
"""
# 让UI竖直上下分布
colunm = cmds.columnLayout()
# 第一行显示静态文本
cmds.text(label="Use the slider to set the tween amount")
# 让UI水平分布,宽度为两个物体
row = cmds.rowLayout(numberOfColumns=2)
# 创建滑块UI
self.slider=cmds.floatSlider(min=0, max=100, value=50, step=1, changeCommand=tween)
# 创建reset按钮
cmds.button(label="Reset", command=self.reset)
# 继续让UI回到竖直分布
cmds.setParent(colunm)
# 创建退出按钮
cmds.button(label="close", command=self.close)
def reset(self,*args):
#*args将该函数其它的参数都存在*args中
"""
让滑块重新设为初始值的函数
:param args:
:return:
"""
cmds.floatSlider(self.slider, edit=True, value=50)
def close(self,*args):
"""
删除窗口的函数
:param args:
:return:
"""
cmds.deleteUI(self.windowName)