Website Youtube GitHub

mGear Framework Forum

What's the purpose of leg_L0_ikcns_ctl

When generating the rig using the template biped from mgear.
A locator looking control named leg_L0_ikcns_ctl gets generated.
Im not sure the purpose of this control as there is leg_L0_ik_ctl

Any ideas?


I think it is just a secondary control.

If I recall correctly, when it builds, it is the parent of the IK control, right? It might be meant to be used to constrain the hand or foot, and still be able to animate the main IK control under that constraint.

We decided to reverse it though, especially for the hands. In a POST script, we flip it, so that it is the secondary offset control. To add some secondary animation under the main IK controls.

Another example for the hand: Constrain a prop to the first control. Still be able to adjust the hand without moving the prop.

Thanks for the reply Chris.
I was going to just F8 and scale the controller small and extract the controls so I don’t select them.

Any chance of sneak peak into that post script?

You can also just delete the shape, and extract it. Then you are guaranteed not to select it. An extracted empty transform works too.

Here is my post script. But I only do it for the hands, seemingly.

I also do a fix, where I orient the hands locally. If I remember, the cns node is world space, and I align it to match the local rotation of the wrist. You might want to omit that for a foot control.

import mgear
import mgear.shifter.custom_step as cstp
import pymel.core as pm
from mgear.core import attribute, transform
from mgear import rigbits

class CustomShifterStep(cstp.customShifterMainStep):
    def __init__(self): = "final_rig_cleanup"
        self.charName = pm.PyNode('guide').rig_name.get()

    def run(self, stepDict):
        for side in 'LR':


    def fix_ik_hand_orientation(self, side):
        # by default, the ik hands are oriented by world.
        # This makes them match the local rotation of the wrist.
        handRef = pm.PyNode('hand_{}0_ctl'.format(side))
        ikCns = pm.PyNode('arm_{}0_ikcns_ctl'.format(side))
        ikCtrl = pm.PyNode('arm_{}0_ik_ctl'.format(side))
        handChildren = ikCtrl.getChildren(type='transform')
        pm.parent(handChildren, None)
        transform.matchWorldTransform(handRef, ikCns)
        transform.matchWorldTransform(handRef, ikCtrl)
        # ALSO SWAP THE ORDER OF THE IK and IK OFFSET. arm_R0_ikcns_ctl should be child.
        pm.parent(ikCtrl, ikCns.getParent())
        pm.parent(ikCns, ikCtrl)
        pm.parent(handChildren, ikCns)
        oRoot = rigbits.addNPO(ikCtrl)[0]
        attribute.lockAttribute(ikCns, attributes=['v'])

Thanks Chris for the script.
I hadn’t thought of the idea of deleting a controller and then extracting controllers again.