Blog

Rigging for Retargeting in Unreal Engine

Posted by:

Unreal has a specific joint naming convention that will speed up retargeting animation if that is part of your pipeline.  You would do well to rename your skinned skeleton to match Unreal’s naming convention.  I have listed the naming convention below.  As naming conventions go, its not that strong.  You will notice that it does not follow traditional naming convention rules in that there is not a standardization in capitalization but whatever.

Center bones:
Root
Pelvis
spine_01
spine_02
spine_03
neck_01 – one might assume that because this joint has a number that Unreal may support more neck bones and distributes the rotation across them but I can’t say that for sure.
head

Joints of the left side:
clavicle_l
UpperArm_L
lowerarm_l
Hand_L
Thigh_L
calf_l
Foot_L
index_01_l
index_02_l
index_03_l
middle, pinky, ring, thumb, etc.
Each of the joints in the list above occur on the right side of the body as well, just replace l or L with r or R.

Also you should know that Unreal has specific skeletal limitations.  You get 3 bones for the spine.  Only 1 bone for the neck. You do however get 1 roll bone for each arm and leg segment, 1 for the upper arm, 1 for the forearm, 1 for the thigh and 1 for the calf.

I have written a script that will rename your joints for the correct Unreal convention.  This is useful if you have a bunch of characters that share the same rig and you want to be able to easily setup retargeting in Unreal, note you will have to alter the directory entries to reflect your skeleton’s naming convention:

  1. #jfm_rename_skeleton.py
  2. #author: Seth Meshko, 3danimationartist.com
  3. #Opens a window that allows the user create a prefix and rename an entire skeleton for retargeting ease in unreal.
  4. #Change the names in the directory to match your rig
  5.  
  6. import maya.cmds as cmds
  7. import functools
  8.  
  9. windowID = 'jfm_rename_skeleton_window'
  10.  
  11. def renameObject(text, dic):
  12. for i, j in dic.iteritems():
  13. text = text.replace(i, j)
  14. return text
  15.  
  16. def renameSkeleton(*args):
  17. prefixName = cmds.textField(prefixNameTextField, editable = True, query = True, text=True)
  18. handList = [prefixName +'LeftHand', prefixName +'RightHand']
  19. print('The hand list is: ' + str(handList))
  20. fingerList = []
  21. for eachHand in handList:
  22. fingerList.extend(cmds.listRelatives(eachHand, allDescendents = True, type = 'joint'))
  23. print('The finger list is: ' + str(fingerList))
  24. for eachJoint in fingerList:
  25. dictionary = {'Hand' : ""}
  26. print('eachJoint is: ' + str(eachJoint))
  27. newName = renameObject(str(eachJoint), dictionary)
  28. newObject = cmds.rename(eachJoint, newName)
  29.  
  30. skeletonRoot = cmds.ls(selection = True)
  31. skeletonList = cmds.listRelatives(skeletonRoot, allDescendents = True, type = 'joint')
  32. skeletonList.insert(0, skeletonRoot[0])
  33. print('The skeleton list is: ' + str(skeletonList))
  34.  
  35. for eachJoint in skeletonList:
  36. print('The joint being checked for ' + str(prefixName) + ' is ' + eachJoint)
  37. if str(prefixName) not in eachJoint:
  38. print(str(prefixName) + 'was not found in ' + eachJoint)
  39. else:
  40. for eachJoint in skeletonList:
  41. dictionary = {str(prefixName) : "", 'Reference' : 'root', 'Hips' : 'pelvis', 'Spine' : 'spine_01', 'Spine1' : 'spine_02', 'Spine2' : 'spine_03',
  42. 'LeftShoulder' : 'clavicle_l', 'RightShoulder' : 'clavicle_r', 'LeftArm' : 'upperarm_l', 'RightArm' : 'upperarm_r', 'LeftForeArm' : 'lowerarm_l', 'RightForeArm' : 'lowerarm_r',
  43. 'LeftHand' : 'hand_l', 'RightHand' : 'hand_r',
  44. 'LeftIndex1' : 'index_01_l', 'LeftIndex2' : 'index_02_l', 'LeftIndex3' : 'index_03_l',
  45. 'RightIndex1' : 'index_01_r', 'RightIndex2' : 'index_02_r', 'RightIndex3' : 'index_03_r',
  46. 'LeftMiddle1' : 'middle_01_l', 'LeftMiddle2' : 'middle_02_l', 'LeftMiddle3' : 'middle_03_l',
  47. 'RightMiddle1' : 'middle_01_r', 'RightMiddle2' : 'middle_02_r', 'RightMiddle3' : 'middle_03_r',
  48. 'LeftRing1' : 'ring_01_l', 'LeftRing2' : 'ring_02_l', 'LeftRing3' : 'ring_03_l',
  49. 'RightRing1' : 'ring_01_r', 'RightRing2' : 'ring_02_r', 'RightRing3' : 'ring_03_r',
  50. 'LeftPinky1' : 'pinky_01_l', 'LeftPinky2' : 'pinky_02_l', 'LeftPinky3' : 'pinky_03_l',
  51. 'RightPinky1' : 'pinky_01_r', 'RightPinky2' : 'pinky_02_r', 'RightPinky3' : 'pinky_03_r',
  52. 'LeftThumb1' : 'thumb_01_l', 'LeftThumb2' : 'thumb_02_l', 'LeftThumb3' : 'thumb_03_l',
  53. 'RightThumb1' : 'thumb_01_r', 'RightThumb2' : 'thumb_02_r', 'RightThumb3' : 'thumb_03_r',
  54. 'Rig_Neck' : 'neck_01', 'Rig_Head' : 'head',
  55. 'LeftUpLeg' : 'thigh_l', 'LeftLeg' : 'calf_l', 'LeftFoot' : 'foot_l', 'LeftToeBase' : 'ball_l',
  56. 'RightUpLeg' : 'thigh_r', 'RightLeg' : 'calf_r', 'RightFoot' : 'foot_r', 'RightToeBase' : 'ball_r', }
  57. newName = renameObject(eachJoint, dictionary)
  58. cmds.rename(eachJoint, newName)
  59.  
  60.  
  61. #Start GUI
  62.  
  63. if cmds.window(windowID, exists=True):
  64. cmds.deleteUI(windowID)
  65.  
  66. cmds.window(windowID, title='SM Rename Skeleton', sizeable=True, width = 500)
  67.  
  68. #Start of 1st frame
  69. cmds.rowColumnLayout(numberOfColumns=1, columnWidth=[(1,500)], columnOffset=[(1,'both', 3)])
  70.  
  71. cmds.text(label = 'Select the root of the skeleton', align = 'center')
  72.  
  73. #Start of 1st frame content
  74. cmds.rowColumnLayout(numberOfColumns=2, columnWidth=[(1,200), (2,300)], columnOffset=[(1,'both', 3)])
  75.  
  76. #horizontal spacer row
  77. cmds.separator(h=10, style='none')
  78. cmds.separator(h=10, style='none')
  79. cmds.setParent('..')
  80.  
  81.  
  82. cmds.text(label = 'Enter the prefix to remove', align = 'center')
  83. prefixNameTextField = cmds.textField(text = 'Sinful_baseSkeleton:BaseRig_')
  84.  
  85.  
  86. #horizontal spacer row
  87. cmds.separator(h=10, style='none')
  88. cmds.separator(h=10, style='none')
  89. cmds.setParent('..')
  90.  
  91. cmds.rowColumnLayout(numberOfColumns=1, columnWidth=[(1,500)], columnOffset=[(1,'both', 3)])
  92. cmds.button(label = 'Rename Skeleton', command = renameSkeleton)
  93.  
  94.  
  95. cmds.showWindow()
0
  Related Posts

You must be logged in to post a comment.