top of page

Scripting

Here's my ctrl-maker script!

I've used this in a lot of projects, as part of my rigging pipeline.


import maya.cmds as cmds
# when this function is a piece of a larger script, the import isn't needed... but having it doesn't break anything so I leave it in!

def ctrl_maker(jnt_name, type="circle"):
    """
    I use this as a building block type thing in a whole lot of autorigs and related scripts

    The joint/control/group naming scheme is one used at my school
    naming convention:
    jnt_name (the parameter for the function) needs to be in quote marks OR ALREADY A STRING or you will get an error
    ex: ctrl_maker("L_test_jnt")
    
    prefix: R_ for right, L_ for left, nothing for center
    postfix: _jnt for joint, _ctrl for controls, _grp for groups around controls,
    _scaleConstraint and _parentConstraint

    By default makes a circle controller. If you want a point controller, type="point"
    Which looks like a little arrowhead.
    """

    # make names
    jnt_prefix = (jnt_name[:-4]) # slice jnt name. [:-4] because "_jnt" is 4 chars
    ctrl_name = jnt_prefix + "_ctrl" # add the control postfix to get the control name
    grp_name = jnt_prefix + "_grp" # add the group postfix to get the group name
    # print (jnt_name + " " + jnt_prefix + " " + ctrl_name + " " + grp_name) #test

    # make ctrl and grp
    if (type == "point"):
        cmds.curve( p=[(0, 0, 0), (-.1, 0, -.07), (-.5, 0, -1.5), (0, 0, -.5), (.5, 0, -1.5), (.1, 0, -.07), (0, 0, 0), (0, -.1, -.07), ( 0, -.5, -1.5), (0, 0, -.5), ( 0,.5, -1.5), ( 0,.1, -.07), (0, 0, 0)] )
    else:
        cmds.circle( nr=(0, 0, 1) ) # make a circle facing Z
    cmds.rename (ctrl_name)
    cmds.group (ctrl_name) # put the control in a group
    cmds.rename (grp_name)

    # move the controller (via the group) to the position and orientation of the joint
    # by adding a parent constraint WITHOUT MAINTAIN OFFSET and then deleting the constraint
    cmds.parentConstraint( jnt_name, grp_name ) #w=1 by default
    parentconstraintname = grp_name + "_parentConstraint1"
    cmds.delete (parentconstraintname)
    # I got this trick from https://stackoverflow.com/a/60540296/23992295 

    # color
    # toggle on display override colors
    # it's a boolean so setting it to 1 is toggling it on
    cmds.setAttr (grp_name + ".overrideEnabled",1)
    cmds.setAttr(grp_name + ".overrideRGBColors",1)
    # I had trouble with the syntax here, eventually found how to write it here
    # https://forums.autodesk.com/t5/maya-programming/how-to-set-rgb-color-for-drawing-overrides-with-python/td-p/7592153

    # Booleans setup for left or right or middle
    startsWith = (grp_name[:2]) # gets the first two letters, which will be either R_, L_, or something else (for middle)
    IsRight=False # false by default
    IsLeft =False
    if (startsWith == "R_"):
        IsRight = True
    if (startsWith == "L_"):
        IsLeft = True

    # set color
    if (IsRight):
        print("red for right!\n")
        # red = 1 0 0 
        cmds.setAttr (grp_name + ".overrideColorR" ,1)
        cmds.setAttr (grp_name + ".overrideColorG" ,0)
        cmds.setAttr (grp_name + ".overrideColorB" ,0)
    elif (IsLeft):
        print("lefty bluesy!\n")
        # blue = 0 0 1
        cmds.setAttr (grp_name + ".overrideColorR" ,0)
        cmds.setAttr (grp_name + ".overrideColorG" ,0)
        cmds.setAttr (grp_name + ".overrideColorB" ,1)
    else:
        print("yellow in the middle!\n")
        cmds.setAttr (grp_name + ".overrideColorR" ,1)
        cmds.setAttr (grp_name + ".overrideColorG" ,1)
        cmds.setAttr (grp_name + ".overrideColorB" ,0)
 
    # constraints, so the control controls the joint
    cmds.parentConstraint (ctrl_name, jnt_name, mo=True, name=jnt_prefix+"_parentConstraint")
    cmds.scaleConstraint (ctrl_name, jnt_name, mo=True, name=jnt_prefix+"_scaleConstraint")


    # make grp attributes nonkeyable
    for suffix in ("tx", "ty", "tz", "rx", "ry", "rz", "sx", "sy", "sz", "v"):
        cmds.setAttr((grp_name + "." + suffix), keyable=False)

    # hooray! All done!

# test
# have a joint selected
foo = cmds.ls( sl=True) or [] #list
selectedjnt = foo[0] # the only item in the list
ctrl_maker(selectedjnt)

Thanks for reading!

bottom of page