#☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺ # # Script: createDynamicTail.py # Author: Audrey Paransky & Simon Burdick # Last Updated: 06/10/2024 # Created: 06/10/2024 # Description: This script creates expression driven dynamics for a joint chain # #☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺ import maya.cmds as cmds selectionList = cmds.ls( orderedSelection=True, type='joint' ) controlPoints = [ (0, 0, 6), (0, -3, 4), (0, -3, 2), (0, 0, 0), (0, 3, -2), (0, 3, -4), (0, 0, -6) ] tailCtrl = cmds.curve( p=controlPoints, d=3, name='tailCtrl' ) firstJoint = cmds.xform(selectionList[0], query = True, translation = True, worldSpace = True) cmds.move(firstJoint[0], firstJoint[1] +5, firstJoint[2], tailCtrl) cmds.rotate(0, 90, 0, tailCtrl) cmds.makeIdentity(tailCtrl, apply=True) # ADD ATTRIBUTES TO TAIL CONTROLLER cmds.addAttr( tailCtrl, shortName='Frequency', longName='Frequency', keyable = True, defaultValue= 0.25, minValue= -1, maxValue= 1 ) cmds.addAttr( tailCtrl, shortName='Amplitude', longName='Amplitude', keyable = True, defaultValue=20, minValue=0, maxValue=100 ) cmds.addAttr( tailCtrl, shortName='Gravity', longName='Gravity', keyable = True, defaultValue=0, minValue=-100, maxValue=100 ) cmds.addAttr( tailCtrl, shortName='OffOn', longName='OffOn', keyable = True, defaultValue=1, minValue=0, maxValue=1 ) # FOR LOOP ASSIGN EXPRESSIONS previousJnt = selectionList[0] for jnt in selectionList: if (jnt == selectionList[0]): cmds.expression(object = jnt, string = f"rotateZ = ((sin((frame * {tailCtrl}.Frequency)) * {tailCtrl}.Amplitude) + {tailCtrl}.Gravity )* {tailCtrl}.OffOn") else: cmds.expression(object = jnt, string = f"rotateZ = `getAttr -t (frame -5) {previousJnt}.rotateZ`") previousJnt = jnt