Many thanks! it worked!
Glad to help!
Finger FK/IK matching
Hi ,
Would it be possible for you check the following code for finger fk/ik matching?
And if it is good I would like to contribute it
in ART_animationUI.py:
def match_finger_ik(self,character,finger,side,*args):
fingerJoints = "01_", "02_", "03_"]
fingerLocators = {}
for index in fingerJoints:
fingerLocators[index] = cmds.spaceLocator()[0]
for index in fingerJoints:
cmds.delete(cmds.parentConstraint(character + ":driver_"+ finger + index + side, fingerLocators[index])[0])
constraints = {}
for index in fingerJoints:
constraints index ] = cmds.orientConstraint( fingerLocators[index ], character + ":" + finger + "finger_fk_ctrl_" + index[1:] + side )[0]
for index in fingerJoints:
cmds.setKeyframe(character + ":" + finger + "finger_fk_ctrl_" + index[1:] + side )
for index in fingerJoints:
cmds.delete(constraints[index])
for index in fingerJoints:
cmds.delete(fingerLocators[index])
def getScaleFactor(self,character):
return cmds.getAttr(character + ":" + "Rig_Settings.scaleFactor")
def match_finger_fk(self,character, finger,side,scaleFactor ,*args):
finger01Loc = cmds.spaceLocator()[0]
finger02Loc = cmds.spaceLocator()[0]
finger03Loc = cmds.spaceLocator()[0]
#constrain to the arm driver joints
cmds.delete(cmds.parentConstraint(character + ":driver_"+ finger + "01_" + side, finger01Loc )[0])
cmds.delete(cmds.parentConstraint(character + ":driver_"+ finger + "02_" + side, finger02Loc )[0])
cmds.delete(cmds.parentConstraint(character + ":driver_"+ finger + "03_" + side, finger03Loc )[0])
#create a fourth locator for the wrist, parent under the handLoc and rotate 90 in X
fingerOffset = cmds.duplicate(finger03Loc)[0]
cmds.parent(fingerOffset, finger03Loc)
if side == "l":
cmds.setAttr(fingerOffset + ".tx",5*scaleFactor)
else:
cmds.setAttr(fingerOffset + ".tx",-5*scaleFactor)
#if side == "l":
# cmds.setAttr(fingerOffset + ".rotateX", 90)
#else:
# cmds.setAttr(fingerOffset + ".rotateX", -90)
#constrain the elbow control to the elbow locator
# if cmds.objExists(character + ":elbowswitch_"+side):
# ptCnst = cmds.pointConstraint(character + ":elbowswitch_"+side, character + ":ik_elbow_" + side + "_anim")
#
# else:
pntConst = cmds.pointConstraint(finger02Loc , character + ":"+ finger+side + "_poleVector")[0]
#constrain the wrist
constraint = cmds.parentConstraint(fingerOffset , character + ":"+ finger + side + "_ik_anim")[0]
#set keys
cmds.setKeyframe(character + ":"+ finger+side + "_poleVector")
cmds.setKeyframe(character + ":"+ finger+ side + "_ik_anim")
# if cmds.objExists(character + ":elbowswitch_"+side):
# cmds.delete(ptCnst)
cmds.delete(constraint)
cmds.delete(pntConst)
cmds.delete(finger01Loc)
cmds.delete(finger02Loc)
cmds.delete(finger03Loc)
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
def match_singleFrame(self, limb, side, matchFrom, matchTo, solveRoll = False, *args):
autoKeyOn = False
if cmds.autoKeyframe(q = True, state = True):
cmds.autoKeyframe(state = False)
autoKeyOn = True
#get the passed in limb, and duplicate the skeleton for that limb's current mode
#for example, if limb is left arm, and matchFrom is IK, then dupe the driver joints (in IK pose) for the left arm and parent to world
character = cmds.symbolButton(self.widgets"activeCharacterThumb"], q = True, ann = True)
armBones = "upperarm_", "lowerarm_", "hand_"]
spineBones = "driver_spine_01", "driver_spine_02", "driver_spine_03", "driver_spine_04", "driver_spine_05"]
legBones = "thigh_", "calf_", "foot_", "ball_"]
fingerBones = "thumb", "index", "middle", "ring", "pinky"]
fingerJoints = "01_", "02_", "03_"]
#grab current selection
currentSelection = cmds.ls(sl = True)
if limb == "fingers":
if matchTo == "IK":
for fingerBone in fingerBones:
self.match_finger_ik(character,fingerBone+"_",side)
if matchTo == "FK":
scaleFactor = self.getScaleFactor(character)
for fingerBone in fingerBones:
self.match_finger_fk(character,fingerBone+"_",side,scaleFactor)
if limb in fingerBones:
if matchTo == "IK":
self.match_finger_ik(character, limb+"_",side)
if matchTo == "FK":
scaleFactor = self.getScaleFactor(character)
self.match_finger_fk(character,limb+"_",side,scaleFactor)
#arm matching
if limb == "arm":
#setup constraints based on mode info
if matchTo == "IK":
#create 3 locators in world space
upArmLoc = cmds.spaceLocator()[0]
lowArmLoc = cmds.spaceLocator()[0]
handLoc = cmds.spaceLocator()[0]
#constrain to the arm driver joints
cmds.delete(cmds.parentConstraint(character + ":driver_upperarm_" + side, upArmLoc)[0])
cmds.delete(cmds.parentConstraint(character + ":driver_lowerarm_" + side, lowArmLoc)[0])
cmds.delete(cmds.parentConstraint(character + ":driver_hand_" + side, handLoc)[0])
#constrain FK controls to the locators
constraint1 = cmds.orientConstraint(upArmLoc, character + ":fk_arm_" + side + "_anim")[0]
constraint2 = cmds.orientConstraint(lowArmLoc, character + ":fk_elbow_" + side + "_anim")[0]
constraint3 = cmds.orientConstraint(handLoc, character + ":fk_wrist_" + side + "_anim")[0]
# constraint1 = cmds.orientConstraint(character + ":ik_upperarm_fk_matcher_" + side, character + ":fk_arm_" + side + "_anim")[0]
# constraint2 = cmds.orientConstraint(character + ":ik_lowerarm_fk_matcher_" + side, character + ":fk_elbow_" + side + "_anim")[0]
# constraint3 = cmds.orientConstraint(character + ":hand_match_loc_" + side, character + ":fk_wrist_" + side + "_anim")[0]
cmds.setKeyframe(character + ":fk_arm_" + side + "_anim")
cmds.setKeyframe(character + ":fk_elbow_" + side + "_anim")
cmds.setKeyframe(character + ":fk_wrist_" + side + "_anim")
cmds.delete(constraint1)
cmds.delete(constraint2)
cmds.delete(constraint3)
cmds.delete(upArmLoc)
cmds.delete(lowArmLoc)
cmds.delete(handLoc)
if matchTo == "FK":
#create 3 locators in world space
upArmLoc = cmds.spaceLocator()[0]
lowArmLoc = cmds.spaceLocator()[0]
handLoc = cmds.spaceLocator()[0]
#constrain to the arm driver joints
cmds.delete(cmds.parentConstraint(character + ":driver_upperarm_" + side, upArmLoc)[0])
cmds.delete(cmds.parentConstraint(character + ":driver_lowerarm_" + side, lowArmLoc)[0])
cmds.delete(cmds.parentConstraint(character + ":driver_hand_" + side, handLoc)[0])
#create a fourth locator for the wrist, parent under the handLoc and rotate 90 in X
handOffset = cmds.duplicate(handLoc)[0]
cmds.parent(handOffset, handLoc)
if side == "l":
cmds.setAttr(handOffset + ".rotateX", 90)
else:
cmds.setAttr(handOffset + ".rotateX", -90)
#constrain the elbow control to the elbow locator
# if cmds.objExists(character + ":elbowswitch_"+side):
# ptCnst = cmds.pointConstraint(character + ":elbowswitch_"+side, character + ":ik_elbow_" + side + "_anim")
#
# else:
pntConst = cmds.pointConstraint(lowArmLoc, character + ":ik_elbow_" + side + "_anim")[0]
#constrain the wrist
constraint = cmds.parentConstraint(handOffset, character + ":ik_wrist_" + side + "_anim")[0]
#set keys
cmds.setKeyframe(character + ":ik_wrist_" + side + "_anim")
cmds.setKeyframe(character + ":ik_elbow_" + side + "_anim")
# if cmds.objExists(character + ":elbowswitch_"+side):
# cmds.delete(ptCnst)
cmds.delete(constraint)
cmds.delete(pntConst)
cmds.delete(upArmLoc)
cmds.delete(lowArmLoc)
cmds.delete(handLoc)
# dupeNodes = cmds.duplicate(character + ":driver_" + armBones[0] + side)
#
# parent = cmds.listRelatives(dupeNodes[0], parent = True)
# if parent != None:
# cmds.parent(dupeNodes[0], world = True)
#
# cmds.pointConstraint("driver_hand_" + side, character + ":ik_wrist_" + side + "_anim")
# constraint = cmds.orientConstraint(character + ":fk_wrist_" + side + "_anim", character + ":ik_wrist_" + side + "_anim")[0]
#
# # CRA NEW CODE - For making sure the elbow match doesnt cause any weird twisting issues.
# if cmds.objExists(character + ":elbowswitch_"+side):
# print "NEW CODE WORKING"
# ptCnst = cmds.pointConstraint(character + ":elbowswitch_"+side, character + ":ik_elbow_" + side + "_anim")
# else:
# cmds.pointConstraint("driver_lowerarm_"+side, character + ":ik_elbow_" + side + "_anim")
# # CRA END NEW CODE
#
# if side == "l":
# cmds.setAttr(constraint + ".offsetX", 90)
#
# if side == "r":
# cmds.setAttr(constraint + ".offsetX", -90)
#
#
# cmds.setKeyframe(character + ":ik_wrist_" + side + "_anim")
# cmds.setKeyframe(character + ":ik_elbow_" + side + "_anim")
#
# # CRA NEW CODE
# if cmds.objExists(character + ":elbowswitch_"+side):
# cmds.delete(ptCnst)
# # CRA END NEW CODE
#
# cmds.delete(constraint)
# #delete the original mode pose joints
# cmds.delete(dupeNodes[0])
if limb == "clav":
#setup constraints based on mode info
if matchTo == "IK":
constraint1 = cmds.orientConstraint(character + ":ik_clavicle_" + side, character + ":fk_clavicle_" + side + "_anim")[0]
cmds.setKeyframe(character + ":fk_clavicle_" + side + "_anim")
cmds.delete(constraint1)
if matchTo == "FK":
constraint1 = cmds.pointConstraint(character + ":driver_upperarm_" + side, character + ":clavicle_" + side + "_anim")[0]
cmds.setKeyframe(character + ":clavicle_" + side + "_anim")
cmds.delete(constraint1)
#leg matching
attrList = cmds.listAttr(character + ":Skeleton_Settings", shortNames=True)
for i in attrList:
if i == "legStyle":
legStyle = cmds.getAttr(character+":Skeleton_Settings.legStyle")
if limb == "leg":
dupeNodes = cmds.duplicate(character + ":" + legBones[0] + side)
parent = cmds.listRelatives(dupeNodes[0], parent = True)
if parent != None:
cmds.parent(dupeNodes[0], world = True)
#setup constraints based on mode info
if matchTo == "IK":
cmds.orientConstraint("thigh_" + side, character + ":fk_thigh_" + side + "_anim")
cmds.orientConstraint("calf_" + side, character + ":fk_calf_" + side + "_anim")
if legStyle == 1:
cmds.orientConstraint("heel_" + side, character + ":fk_heel_" + side + "_anim")
cmds.orientConstraint("foot_" + side, character + ":fk_foot_" + side + "_anim")
if cmds.objExists("ball_" + side):
cmds.orientConstraint("ball_" + side, character + ":fk_ball_" + side + "_anim")
cmds.setKeyframe(character + ":fk_thigh_" + side + "_anim")
cmds.setKeyframe(character + ":fk_calf_" + side + "_anim")
if legStyle == 1:
cmds.setKeyframe(character + ":fk_heel_" + side + "_anim")
cmds.setKeyframe(character + ":fk_foot_" + side + "_anim")
if cmds.objExists("ball_" + side):
cmds.setKeyframe(character + ":fk_ball_" + side + "_anim")
if matchTo == "FK":
cmds.select(clear = True)
loc1 = character + ":matchLoc_knee_1_" + side
loc2 = character + ":matchLoc_knee_2_" + side
#setup constraints
for ctrl in ":heel_ctrl_" + side, ":toe_wiggle_ctrl_" + side, ":toe_tip_ctrl_" + side, ":ik_foot_anim_" + side]:
cmds.select(character + ctrl, add = True)
self.resetSelection()
cmds.setKeyframe()
#reverse foot matching setup
if solveRoll:
if cmds.objExists(character + ":fk_ball_" + side + "_anim"):
cmds.refresh(force = True)
footLoc = cmds.spaceLocator(name = character + ":matchLoc_foot_" + side)[0]
ikFootLoc = cmds.spaceLocator(name = character + ":matchLoc_ik_foot_" + side)[0]
toeLoc = cmds.spaceLocator(name = character + ":matchLoc_toe_" + side)[0]
cmds.parent(footLoc, character + ":fk_ball_" + side + "_anim")
cmds.parent(toeLoc, character + ":fk_foot_" + side + "_anim")
cmds.parentConstraint(character + ":fk_foot_" + side + "_anim", footLoc)
cmds.parentConstraint(character + ":fk_ball_" + side + "_anim", toeLoc)
const = cmds.parentConstraint(character + ":master_foot_ball_pivot_" + side, ikFootLoc)[0]
cmds.delete(const)
#world position locators
startPos = cmds.spaceLocator()[0]
midPos = cmds.spaceLocator()[0]
endPos = cmds.spaceLocator()[0]
cmds.parentConstraint(footLoc, startPos)
cmds.parentConstraint(toeLoc, midPos)
cmds.parentConstraint(character + ":foot_ikHandle_" + side, endPos)
else:
solveRoll = False
if not solveRoll:
loc = cmds.spaceLocator(name = character + ":ik_foot_anim_" + side + "_locator")[0]
constraint = cmds.parentConstraint("foot_" + side, loc)[0]
cmds.delete(constraint)
cmds.pointConstraint(loc, character + ":ik_foot_anim_" + side)
constraint = cmds.orientConstraint(loc, character + ":ik_foot_anim_" + side)[0]
if side == "l":
cmds.setAttr(constraint + ".offsetY", 90)
if side == "r":
cmds.setAttr(constraint + ".offsetX", 180)
cmds.setAttr(constraint + ".offsetY", 90)
else:
ikFootConst = cmds.parentConstraint(ikFootLoc, character + ":ik_foot_anim_" + side, mo = True)[0]
cmds.parentConstraint(toeLoc, ikFootLoc)
cmds.setAttr(character + ":Rig_Settings." + side + "LegMode", 1)
cmds.setKeyframe(character + ":Rig_Settings." + side + "LegMode")
#heel solve
self.ikHeelSolve(character, side, startPos, midPos, endPos)
cmds.setAttr(character + ":Rig_Settings." + side + "LegMode", 0)
cmds.setKeyframe(character + ":Rig_Settings." + side + "LegMode")
cmds.setKeyframe(character + ":ik_foot_anim_" + side)
#knee solve
for x in range(1500):
angle = self.getAngleBetween(loc1, loc2)
if abs(angle) > .25:
self.ikKneeSolve(character, side, angle, loc1, loc2)
else:
break
if not solveRoll:
cmds.delete(loc)
else:
cmds.delete(footLoc)
cmds.delete(ikFootLoc)
cmds.delete(toeLoc)
cmds.setKeyframe(character + ":ik_foot_anim_" + side)
#delete the original mode pose joints
cmds.delete(dupeNodes[0])
#spine matching
if limb == "spine":
dupeNodes = cmds.duplicate(character + ":" + spineBones[0])
parent = cmds.listRelatives(dupeNodes[0], parent = True)
if parent != None:
cmds.parent(dupeNodes[0], world = True)
#setup constraints based on mode info
# Switching to FK
if matchTo == "IK":
#check to see if user has any project specific match scripts (Fortnite custom)
if cmds.objExists(character + ":spine_02_anim.driven"):
#furthermore, if the plusMinusAvg nodes exist, then import custom matching
if os.path.exists(self.mayaToolsDir + "/General/Scripts/fortniteRotoMatch.py"):
result = cmds.confirmDialog(title = "Match Options", icon = "question", message = "Which match option would you like to use?", button = "Standard", "Rotoscope"])
if result == "Standard":
try:
cmds.setAttr(character + ":spine_02_anim.driven", 0)
cmds.setAttr(character + ":spine_04_anim.driven", 0)
except:
pass
if cmds.objExists(character + ":spine_01_anim"):
cmds.orientConstraint("driver_spine_01", character + ":spine_01_anim")
cmds.setKeyframe(character + ":spine_01_anim")
if cmds.objExists(character + ":spine_02_anim"):
cmds.orientConstraint("driver_spine_02", character + ":spine_02_anim")
cmds.setKeyframe(character + ":spine_02_anim")
if cmds.objExists(character + ":spine_03_anim"):
cmds.orientConstraint("driver_spine_03", character + ":spine_03_anim")
cmds.setKeyframe(character + ":spine_03_anim")
if cmds.objExists(character + ":spine_04_anim"):
cmds.orientConstraint("driver_spine_04", character + ":spine_04_anim")
cmds.setKeyframe(character + ":spine_04_anim")
if cmds.objExists(character + ":spine_05_anim"):
cmds.orientConstraint("driver_spine_05", character + ":spine_05_anim")
cmds.setKeyframe(character + ":spine_05_anim")
#for each in spineBones:
#if cmds.objExists(character + ":" + each + "_anim"):
#cmds.setKeyframe(character + ":" + each + "_anim")
if result == "Rotoscope":
import fortniteRotoMatch as fnRm
reload(fnRm)
fnRm.RotoSpineMatch(character)
else:
if cmds.objExists(character + ":spine_01_anim"):
cmds.orientConstraint("driver_spine_01", character + ":spine_01_anim")
cmds.setKeyframe(character + ":spine_01_anim")
if cmds.objExists(character + ":spine_02_anim"):
cmds.orientConstraint("driver_spine_02", character + ":spine_02_anim")
cmds.setKeyframe(character + ":spine_02_anim")
if cmds.objExists(character + ":spine_03_anim"):
cmds.orientConstraint("driver_spine_03", character + ":spine_03_anim")
cmds.setKeyframe(character + ":spine_03_anim")
if cmds.objExists(character + ":spine_04_anim"):
cmds.orientConstraint("driver_spine_04", character + ":spine_04_anim")
cmds.setKeyframe(character + ":spine_04_anim")
if cmds.objExists(character + ":spine_05_anim"):
cmds.orientConstraint("driver_spine_05", character + ":spine_05_anim")
cmds.setKeyframe(character + ":spine_05_anim")
#for each in spineBones:
#if cmds.objExists(character + ":" + each + "_anim"):
#cmds.setKeyframe(character + ":" + each + "_anim")
# Switching to IK
if matchTo == "FK":
if cmds.objExists(character + ":chest_ik_anim"):
#find highest spine joint
numSpineBones = cmds.getAttr(character + ":Skeleton_Settings.numSpineBones")
if numSpineBones == 5:
endSpine = "driver_spine_05"
midSpine = "driver_spine_03"]
if numSpineBones == 4:
endSpine = "driver_spine_04"
midSpine = "driver_spine_02", "driver_spine_03"]
if numSpineBones == 3:
endSpine = "driver_spine_03"
midSpine = "driver_spine_02"]
if cmds.objExists("chest_ik_anim_MATCH"):
cmds.parentConstraint("chest_ik_anim_MATCH", character + ":chest_ik_anim")
cmds.parentConstraint("mid_ik_anim_MATCH", character + ":mid_ik_anim")
else:
cmds.parentConstraint(endSpine, character + ":chest_ik_anim")
for each in midSpine:
cmds.parentConstraint(each, character + ":mid_ik_anim")
cmds.setKeyframe([character + ":chest_ik_anim", character + ":mid_ik_anim"])
#delete the original mode pose joints
cmds.delete(dupeNodes[0])
#reselect selection before entering process
if len(currentSelection) > 0:
cmds.select(currentSelection)
if autoKeyOn:
cmds.autoKeyframe(state = True)
in ART_autorigger.py:
class AutoRigger():
def __init__(self, handCtrlSpace, progressBar):
self.handCtrlSpace = handCtrlSpace
#get access to our maya tools
toolsPath = cmds.internalVar(usd = True) + "mayaTools.txt"
if os.path.exists(toolsPath):
f = open(toolsPath, 'r')
self.mayaToolsDir = f.readline()
f.close()
#create a progress window to track the progress of the rig build
self.progress = 0
cmds.progressBar(progressBar, edit = True, progress=self.progress, status='Creating Spine Rig')
#build the core of the rig
import Modules.ART_Core
coreNodes = Modules.ART_Core.RigCore()
cmds.select("Rig_Settings",r=True)
cmds.addAttr(ln="scaleFactor",at="float", keyable = False)
cmds.setAttr("Rig_Settings."+"scaleFactor",utils.getScaleFactor(),lock=True)
cmds.select(cl=True)
#BODY CONTROL
self.buildHips()
"""
#create the rig settings node
"Rig_Settings" = cmds.group(empty = True, name = "Rig_Settings")
cmds.setAttr("Rig_Settings" + ".tx", lock = True, keyable = False)
cmds.setAttr("Rig_Settings" + ".ty", lock = True, keyable = False)
cmds.setAttr("Rig_Settings" + ".tz", lock = True, keyable = False)
cmds.setAttr("Rig_Settings" + ".rx", lock = True, keyable = False)
cmds.setAttr("Rig_Settings" + ".ry", lock = True, keyable = False)
cmds.setAttr("Rig_Settings" + ".rz", lock = True, keyable = False)
cmds.setAttr("Rig_Settings" + ".sx", lock = True, keyable = False)
cmds.setAttr("Rig_Settings" + ".sy", lock = True, keyable = False)
cmds.setAttr("Rig_Settings" + ".sz", lock = True, keyable = False)
cmds.setAttr("Rig_Settings" + ".v", lock = True, keyable = False)
#build the spine rigs
self.createDriverSkeleton()
self.buildCoreComponents()
"""
#to be replaced by modules
fkControls = self.buildFKSpine()
ikControls = self.buildIKSpine(fkControls)
#build the leg rigs
#first determine the leg style
legStyle = cmds.getAttr("SkeletonSettings_Cache.legStyle")
if legStyle == "Standard Biped":
cmds.progressBar(progressBar, edit = True, progress = 20, status='Creating Leg Rigs')
self.buildFKLegs()
self.buildIKLegs()
self.finishLegs()
cmds.progressBar(progressBar, edit = True, progress = 30, status='Creating Toe Rigs')
self.buildToes()
cmds.progressBar(progressBar, edit = True, progress = 40, status='Creating Auto Hips and Spine')
self.buildAutoHips()
self.autoSpine()
if legStyle == "Hind Leg":
cmds.progressBar(progressBar, edit = True, progress = 20, status='Creating Leg Rigs')
self.buildFKLegs_hind()
self.buildIKLegs_hind()
self.finishLegs_hind()
cmds.progressBar(progressBar, edit = True, progress = 30, status='Creating Toe Rigs')
self.buildToes()
cmds.progressBar(progressBar, edit = True, progress = 40, status='Creating Auto Hips and Spine')
self.buildAutoHips()
self.autoSpine()
#build the arms
cmds.progressBar(progressBar, edit = True, progress = 50, status='Creating Arm Rigs')
spineBones = self.getSpineJoints()
lastSpine = "driver_" + spineBones-1]
print lastSpine
import Modules.ART_Arm
reload(Modules.ART_Arm)
Modules.ART_Arm.Arm(True, "", None, "l", lastSpine, 6, True)
Modules.ART_Arm.Arm(True, "", None, "r", lastSpine, 13, True)
"""
self.buildFKArms()
self.buildIkArms()
"""
cmds.progressBar(progressBar, edit = True, progress = 60, status='Creating Finger Rigs')
self.buildFingers()
#build the neck and head rig
cmds.progressBar(progressBar, edit = True, progress = 70, status='Creating Neck and Head Rigs')
self.buildNeckAndHead()
#rig extra joints
cmds.progressBar(progressBar, edit = True, progress = 80, status='Creating Rigs for Custom Joints')
createdControls = self.rigLeafJoints()
createdJiggleNodes = self.rigJiggleJoints()
createdChainNodes = self.rigCustomJointChains()
#clean up the hierarchy
cmds.progressBar(progressBar, edit = True, progress = 90, status='Cleaning up Scene')
bodyGrp = cmds.group(empty = True, name = "body_grp")
for obj in "spine_splineIK_curve", "splineIK_spine_01_splineIK", "body_anim_space_switcher_follow"]:
if cmds.objExists(obj):
cmds.parent(obj, bodyGrp)
if cmds.objExists("autoHips_sys_grp"):
cmds.parent("autoHips_sys_grp", "body_anim")
rigGrp = "ctrl_rig"
cmds.parent([bodyGrp, "leg_sys_grp"], rigGrp)
"""
rigGrp = cmds.group(empty = True, name = "ctrl_rig")
cmds.parent([bodyGrp, "leg_sys_grp", "Rig_Settings"], rigGrp)
cmds.parent(rigGrp, "offset_anim")
"""
#Arms
"""
if cmds.objExists("arm_rig_master_grp_l"):
cmds.setAttr("Rig_Settings.lArmMode", 1)
if cmds.objExists("lowerarm_l_roll_grp"):
cmds.parent("lowerarm_l_roll_grp", "arm_rig_master_grp_l")
cmds.parent("arm_rig_master_grp_l", "ctrl_rig")
if cmds.objExists("arm_rig_master_grp_r"):
cmds.setAttr("Rig_Settings.rArmMode", 1)
if cmds.objExists("lowerarm_r_roll_grp"):
cmds.parent("lowerarm_r_roll_grp", "arm_rig_master_grp_r")
cmds.parent("arm_rig_master_grp_r", "ctrl_rig")
if cmds.objExists("arm_rig_master_grp_r") and cmds.objExists("arm_rig_master_grp_l"):
armSysGrp = cmds.group(empty = True, name = "arm_sys_grp")
cmds.parent(armSysGrp, "ctrl_rig")
cmds.parent("arm_rig_master_grp_r", "arm_rig_master_grp_l", "ik_wrist_l_anim_space_switcher_follow", "ik_wrist_r_anim_space_switcher_follow"], armSysGrp)
#arm twists
if cmds.objExists("upperarm_twist_grp_l"):
cmds.parent("upperarm_twist_grp_l", armSysGrp)
if cmds.objExists("upperarm_twist_grp_r"):
cmds.parent("upperarm_twist_grp_r", armSysGrp)
"""
if cmds.objExists("neck_01_fk_anim_grp"):
cmds.parent("neck_01_fk_anim_grp", "ctrl_rig")
#Fingers
if cmds.objExists("finger_sys_grp_l"):
cmds.parent("finger_sys_grp_l", "ctrl_rig")
if cmds.objExists("finger_sys_grp_r"):
cmds.parent("finger_sys_grp_r", "ctrl_rig")
#Custom Joints (leaf, jiggle, chain)
if len(createdControls) > 0:
for each in createdControls:
cmds.parent(each, "ctrl_rig")
if len(createdJiggleNodes) > 0:
for each in createdJiggleNodes:
cmds.parent(each, "ctrl_rig")
if len(createdChainNodes) > 0:
for each in createdChainNodes:
cmds.parent(each, "ctrl_rig")
cmds.parent("head_sys_grp", "ctrl_rig")
#finish grouping everything under 1 character grp
if cmds.objExists("Proxy_Geo_Skin_Grp"):
try:
cmds.parent("Proxy_Geo_Skin_Grp", "rig_grp")
except:
pass
if cmds.objExists("dynHairChain"):
try:
cmds.parent("dynHairChain", "rig_grp")
except:
pass
#add world spaces to each space switch control
self.addSpaces()
#Hide all joints
joints = cmds.ls(type = 'joint')
for joint in joints:
if cmds.getAttr(joint + ".v", settable = True):
cmds.setAttr(joint + ".v", 0)
cmds.progressBar(progressBar, edit = True, progress = 100, status='Cleaning up Scene')
#delete the joint mover
cmds.select("root_mover_grp", r = True, hi = True)
cmds.select("Skeleton_Settings", add = True)
nodes = cmds.ls(sl = True, transforms = True)
cmds.select(clear = True)
for node in nodes:
cmds.lockNode(node, lock = False)
cmds.lockNode("JointMover", lock = False)
cmds.delete("JointMover")
#find and delete junk nodes/clean scene
for obj in "invis_legs_Rig_Settings", "invis_legs_Rig_Settings1", "invis_legs_spine_splineIK_curve", "invis_legs_spine_splineIK_curve1","invis_legs_master_anim_space_switcher_follow", "invis_legs_master_anim_space_switcher_follow1"]:
try:
cmds.select("*" + obj + "*")
selection = cmds.ls(sl = True)
for each in selection:
if cmds.objExists(each):
cmds.delete(each)
except:
pass
cmds.select(all = True)
selection = cmds.ls(sl = True)
for each in selection:
if each.find("invis_") == 0:
try:
parent = cmds.listRelatives(each, parent = True)
if parent == None:
cmds.delete(each)
except:
pass
#New IK KNEE MATCHING STUFF!
loc1 = cmds.spaceLocator(name = "matchLoc_knee_1_l")
loc2 = cmds.spaceLocator(name = "matchLoc_knee_2_l")
constraint = cmds.pointConstraint("fk_calf_l_anim", loc1)[0]
cmds.delete(constraint)
cmds.parent(loc1, "fk_calf_l_anim")
constraint = cmds.pointConstraint("ik_leg_calf_l", loc2)[0]
cmds.delete(constraint)
cmds.parent(loc2, "ik_leg_calf_l")
cmds.select(loc1)
cmds.move(0, -30, 0, r = True)
cmds.select(loc2)
cmds.move(0, -30, 0, r = True)
cmds.setAttr(loc1[0] + ".v", 0)
cmds.setAttr(loc2[0] + ".v", 0)
loc1 = cmds.spaceLocator(name = "matchLoc_knee_1_r")
loc2 = cmds.spaceLocator(name = "matchLoc_knee_2_r")
constraint = cmds.pointConstraint("fk_calf_r_anim", loc1)[0]
cmds.delete(constraint)
cmds.parent(loc1, "fk_calf_r_anim")
constraint = cmds.pointConstraint("ik_leg_calf_r", loc2)[0]
cmds.delete(constraint)
cmds.parent(loc2, "ik_leg_calf_r")
cmds.select(loc1)
cmds.move(0, -30, 0, r = True)
cmds.select(loc2)
cmds.move(0, -30, 0, r = True)
cmds.setAttr(loc1[0] + ".v", 0)
cmds.setAttr(loc2[0] + ".v", 0)
#set default rotate Orders
self.setDefaultRotateOrders()
#end progress window
cmds.select(clear = True)
Motion Import bug
There is a bug in the motion import class that causes the an incorrect project path to be stored if there is a reference with “Project” in it’s path but not in the ART project path.
This causes the import motion class not being able to read the saved animation.
Solution:
class ImportMotionUI():
def __init__(self, uiInst):
#create class variables
self.widgets = {}
self.selection = cmds.ls(sl = True)
self.uiInst = uiInst
#get access to our maya tools
toolsPath = cmds.internalVar(usd = True) + "mayaTools.txt"
if os.path.exists(toolsPath):
f = open(toolsPath, 'r')
self.mayaToolsDir = f.readline()
f.close()
#find out which project we are in
references = cmds.ls(type = "reference")
for ref in references:
try:
query = cmds.referenceQuery(ref, filename = True)
#check if the reference is in the ART project path
if query.find(self.mayaToolsDir) != -1:
self.project = query.rpartition("Projects/")[2].partition("/")[0]
except:
pass
I’m using A.R.T.1.0 in Maya 2016. After turning off the AIM, twists the arms and legs do not move to the correct position. rotation correct
@lion032 OR ANYONE D: Please help, im trying to edit an existing animation. When i click thru the frames and for example turning the character upside down and then change frame, go back to edited frame.Then the frame stays the same as before i edited it. How do i save án edited frame in an animation?
Add the controllers you want to edit to an animation layer edit them there and key that.
Thank you, got it working! I have 1 more question. How do i mirror left hand to right hand inside an animation frame. And after that how can i copy the frame to next frame so i can continue animating from there?
To mirror animation you’ll need to get the Maya bonus tools form here:
https://apps.autodesk.com/en/Detail/Index?id=8115150172702393827&appLang=en&os=Win64&autostart=true
And here is how to use them:
Thank you so much!
Can i ask you one more thing? I have imported an idle animation. I want the hands to be raised in a certain way every frame. I dont want to change anything else. Is there a way to copy the arms only from frame to frame?
To be honest I started animating only about a month ago so the next approach might be the not best one but this is how I would have approached it.
- Using the pose editor of ART save the pose you want for the body.
- Add all of the controllers you want to remain the same to an override animation layer.
- On frame 0 of the override layer right click the layer and select layer objects.
- With override layer objects selected right click the saved pose and click on “Load World space on selected controllers”
Anyone else having a hell of a time exporting looping animations with jiggle joints? Even though the loop is perfect and smooth in Maya, when I export it into the engine the jiggle bones snap pretty hard.
I’m going to ask an incredibly stupid question and I hope someone can answer it for me. Given a FBX - a model that was made in a different program (Cinema4d) - is there any good way to get it into ART? We have the C4D files for it, can export it any way C4D will export.
Getting the file into ART shouldn’t be the issue since it allready is .fbx, but you will need to redo all the advanced setups like IK/FK, Constraints, Helpers etc. even on a reimport to Cinema, because these things don’t transfer over to fbx.
So if you have a animatable rig in .c4d format, you either animate it there and export the results or you just export the model and skeleton and set up the rig in the app you’re going to animate it in.
The reason is simple: while every program uses much similar principles of animation, each one has it’s own setup for these funktions and they cannot be converted.
For Example: if you use Coffee scripts in Cinema 4D to make a chain of bones behave a certain way when rotating a helper object (FK), Maya might have a much similar setup, but wouldn’t understand the Coffee script even if it was possible to export it.
I guess it’s not even possible to transfer rigs between Max and Maya, allthough they are both owned by the same company.
Thaaat’s what I was afraid of. I was given a 2017 .mb, and all I have is 2014. Can’t roll it back nohow!
I have rigged my fbx character using the Maya A.R.T, and I built a .mb file. This is my mesh with a skeleton, correct? How do I import this into UE (as it’s not a .fbx file but a .mb file)?
Hey Mykita,
To get it into engine, you need to open the export file in Maya, select your geometry, select your joints, then export as an FBX. With that FBX you should be able to import into the engine.
Hi guys,
I’m using A.R.T.1.0 from the marketplace for the first time, Maya 2017 and Engine v4.14. I’m just building the rig with default values, and getting the following error:
Any idea how to fix? I didn’t see an answer in this thread yet. Also, when I run the Character Rig Creator, a few pieces of the proxy character meshes have a display issue, the entire right arm and the right thigh…
Any help would be greatly appreciated!
Davidhammertime,
Not sure about the first problem you’re having, but have you made sure to update with the latest version from 's dropbox (link on first page of this thread). That helped with some starter problems I was having in Maya 2016, and the one on the marketplace is not as up-to-date.
The second issue is an easy one. It’s just a visual error and displays those pieces incorrectly in viewport 2.0. If you switch over to legacy viewport it will display the proxy meshes correctly.
kcarter,
Thanks for the reply. Viewport 2.0 issue makes sense. I did try the dropbox version as well as the marketplace version, but I am on a mac as well. I am using the mac version in the dropbox folder, but still getting errors, and a lot of the windows are too small to see all the options. I saw some fixes online for the windows being too small and buttons getting cut-off, but those fixes didn’t seem to work for me. I was having enough issues with it, that I decided to use The Setup Machine from Anzovin Studios for now, as I’ve used that auto-rigger before and it seems to be pretty stable overall.