Stretchy Limb Script Update


After doing a bit more research and asking some questions on the Autodesk Forums, I found out what I had been doing wrong. When you store joints, locators, nodes, etc as python Objects, you can use maya’s “_#” naming functionality and you will thus be able to get unique names.

Now my script can run as many times as needed and every object will be uniquely named. Perfect!

import maya.cmds as cmds

Ben Morgan
SJSU Animation/Illustration

Creates a 2 joint IK chain with a stretchy limb nodal setup.

Note: Scale the "Control Group" to change the size of the limb. The upper and lower limbs
are 1:1 proportion.

def setupStretchyLimb():

# create the joint chain.
upLimb = cmds.joint(n="upLimb#",p=(0,0,0),rad=.3)
lowLimb = cmds.joint(n="lowLimb#",p=(1,0,.001),rad=.3)
endLimb = cmds.joint(n="endLimb#",p=(2,0,0),rad=.3)
# create the IK handle and Distance Dimension
stretchyIK = cmds.ikHandle()
stretchyIK[0] = cmds.rename(stretchyIK[0],"stretchyIK#")
distShapeStart = cmds.spaceLocator(n="distShapeStart#")
distShapeEnd = cmds.spaceLocator(n="distShapeEnd#")
stretchyDist = cmds.distanceDimension(sp=(0,0,0),ep=(2,0,0))
i = cmds.pickWalk(d="down")
stretchyDistShape = i[0]
limbAnim = cmds.spaceLocator(n="limbAnim#")

# this is important as it ensures we don't get the "cycle check" error

# organize everything into groups
jointGrp =,n="jointGrp#")
controlGrp =,distShapeEnd,stretchyDist,limbAnim,stretchyIK[0],n="controlGrp#")
limbGrp =,controlGrp,n="limbGrp#")

# this variable will allow us to scale our rig to work at any size
globalScale = cmds.getAttr(controlGrp + ".sx")

# create our nodes
distCompensate = cmds.createNode("multiplyDivide",n="distCompensate#")
currDist = cmds.createNode("multiplyDivide",n="currDist#")
scaleCompensate = cmds.createNode("multiplyDivide",n="scaleCompensate#")
scaleCondition = cmds.createNode("condition",n="scaleCondition#")

# Set and connect attributes to our distCompensate node
cmds.setAttr(distCompensate + ".i1x",2)
cmds.connectAttr(controlGrp + ".sx",distCompensate + ".i2x")
cmds.connectAttr(distCompensate + ".ox",currDist + ".i2x")
cmds.connectAttr(stretchyDistShape + ".distance", currDist + ".i1x")

# Set and connect attributes to our currentDistance node, the node which
# compensates for the scale of the rig.
cmds.setAttr(currDist + ".op",2)
cmds.connectAttr(currDist + ".ox", scaleCompensate + ".i2x")
cmds.connectAttr(controlGrp + ".sx", scaleCompensate + ".i1x")

# Set and connect attributes to the scaleCondition node, the node which will
# check if the curent distance (which has been divided by the scale of the rig) is greater than 1
cmds.connectAttr(scaleCompensate + ".ox",scaleCondition + ".ctr")
cmds.connectAttr(controlGrp + ".sx",scaleCondition + ".cfr")
cmds.setAttr(scaleCondition + ".op",2)
cmds.connectAttr(currDist + ".ox",scaleCondition + ".ft")
cmds.setAttr(scaleCondition + ".st",1)

cmds.connectAttr(scaleCondition + ".ocr",lowLimb + ".tx")
cmds.connectAttr(scaleCondition + ".ocr",endLimb + ".tx")

# Hide shapes for ease of use
cmds.setAttr(distShapeEnd[0] + ".visibility",0)
cmds.setAttr(stretchyIK[0] + ".visibility",0)

# Move the pivots into the correct position at the beginning of the joint.
cmds.xform(controlGrp + ".scalePivot",t=(0,0,0))
cmds.xform(controlGrp + ".rotatePivot",t=(0,0,0))
cmds.xform(jointGrp + ".scalePivot",t=(0,0,0))
cmds.xform(jointGrp + ".rotatePivot",t=(0,0,0))
cmds.xform(limbGrp + ".scalePivot",t=(0,0,0))
cmds.xform(limbGrp + ".rotatePivot",t=(0,0,0))



Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s