Thanks for sharing how you fixed it, I’ll adjust the addon soon™ too. Feels like that armature offset is also caused by the “new” Mixamo, given how previously I never had that issue…
That flipping is still a small quirk in my addon though, it always makes the armature origin is the identity matrix while it should probably be the HRP matrix instead. Roblox their rig generation plugin creates rigs with the HRP rotated 180 degrees around (0, 1, 0), so it causes those issues with Mixamo if you wouldn’t rotate that rig around first (to ensure the HRP rotation matrix is also the identity one)…
If anyone could make a video on how to animate multiple ROBLOX rigs at the same time, and individually export their animation code as separate, that’d be awesome! Thanks!
I looked for the github repository for this, but can’t find it, only links to the RAW source. Is it online somewhere, forkable?
My changes were just a few lines, to the two functions below. I added comments starting with AYB where I made additions. I used this with the Roblox Rig Generator’s Woman Rig most recently. I also left in a line commented out, which has additional translation and rotation corrections that I needed for the first rig I exported, since I messed up my prep work somehow, either from Roblox to Blender, or when I exported the FBX from Blender (there are too many settings permutations, especially for scaling!)
I was never able to get new Mixamo to properly accept a Roblox character FBX with mesh, but it will take just the armature, and I can see the dancing blue stick figure enough to know it works. I used the modified script with your plugin’s Map keyframes by bone name option with the Mixamo rig selected, not the Import FBX option. I’m unsure if the latter works. I imported the Mixamo-generated animation FBX with Blender’s built-in Import->FBX.
def copy_anim_state_bone(target, source, bone):
# get transform mat of the bone in the source ao
bpy.context.scene.objects.active = source
t_mat = source.pose.bones[bone.name].matrix
#AYB - Root rig world position/orientation we ultimately need transferred to the Lower Torso
w_mat = source.matrix_world
bpy.context.scene.objects.active = target
# root bone transform is ignored, this is carried to child bones (keeps HRP static)
if bone.parent:
# apply transform w.r.t. the current parent bone transform
r_mat = bone.bone.matrix_local
p_mat = bone.parent.matrix
p_r_mat = bone.parent.bone.matrix_local
bone.matrix_basis = (p_r_mat.inverted() * r_mat).inverted() * (p_mat.inverted() * t_mat)
else:
#AYB - Setting the matrix_basis for humanoid root part to the source rig translation and orientation
#so that this world orientation propagates down the armature to all bones, then afterwards I
#will set it back to the identity in copy_anim_state below
r_mat = bone.bone.matrix_local
#AYB - This commented out line was to fix translation and rotation issues I had with my first attempt to export a rig from Roblox
#bone.matrix_basis = Matrix.Translation(Vector((0,2.32211,0))) * ((r_mat.inverted() * (w_mat.inverted() * t_mat)) * Matrix.Rotation(math.radians(180),4,'Y'))
bone.matrix_basis = (r_mat.inverted() * (w_mat.inverted() * t_mat))
# update properties (hacky :p)
bpy.ops.anim.keyframe_insert()
bpy.context.scene.frame_set(bpy.context.scene .frame_current)
# now apply on children (which use the parents transform)
for ch in bone.children:
copy_anim_state_bone(target, source, ch)
def copy_anim_state(target, source):
# to pose mode
bpy.context.scene.objects.active = source
bpy.ops.object.mode_set(mode='POSE')
bpy.context.scene.objects.active = target
bpy.ops.object.mode_set(mode='POSE')
for i in range(bpy.context.scene.frame_start, bpy.context.scene.frame_end+1):
bpy.context.scene.frame_set(i)
copy_anim_state_bone(target, source, root)
#AYB - Setting HRP back to identity CFrame orientation
root.matrix_basis = Matrix.Identity(4)
bpy.ops.anim.keyframe_insert()
That’s normal, I basically attach mesh objects to bones once they’re being imported to emulate the blocky Roblox rig rather than constructing a skinned rig (which is what the rest of the world uses and what Mixamo expects).
Thanks for your changes anyway. I’m considering a slightly alternation now: first move all armature object animations to HRP bone (in world space like you did) on the imported rig and clearing all the entire animation tracks on the armature object. Then the imported armature object can simply be translated and rotated to correct for messed up positioning/rotation (this isn’t really possible until the animation track is removed from the armature object, as you’d be editing a single keyframe otherwise).
I have updated the Blender addon now to mostly handle the new Mixamo stuff properly, see link in first post.
There is now also a way to manually adjust rigs + apply the armature object transform. If you simply use the “Import FBX” button, this will also be applied automatically (which should resolve the problem of the HRP <-> LowerTorso joints not properly moving automatically).
If you want to manually adjust an armature, see this video:
(Transform the entire armature in object mode, then use “Apply armature transform” to apply your transformation to the root bone so the actual animation gets offset once you use “Map keyframes by bone names”.)
In general with the new Mixamo I’d recommend making sure the Position is (0, 2.35, 0) and orientation (0, 0, 0) (for R15 rig, default hip height) before exporting from Roblox. This avoids you having to manually adjust the imported Mixamo animation.
Okay, so I tried re-naming the _RigMeta and _Rig names in Blender, and once I did that (I just put a 2 after the names) I try to import the other rig but it still disappears and is replaced with the newly imported rig. If I could get some help, that’d be great. Thanks!
It deletes everything in the current scene if you try to import a rig.
This should work to circumvent that:
Create a new scene (so two scenes)
Import a rig in one scene + generate the armature (rebuild rig), rename every mesh, the armature and the meta object to something else. Every object in Blender must have a unique name. Once you have created the armature, the addon creates all references between the meshes + bones, so then you can safely rename them. (do not rename the armature bones, only the objects)
Link objects from one scene to another, so you get references to both armatures + meshes in a single scene (select all (A), make link (Ctrl+L), objects to scene)
Now you have two armatures you can safely animate independently.
Whenever exporting the animation back to Roblox again, it will export the animation of the __Rig armature, so rename the armatures around or so to export the armature you want. You don’t need to rename anything else besides this armature. (__RigMeta is only used to initialize the armature properly whenever generating a rig)
The amount of frames (excluding one boundary frame) divided by the frame rate is the time it takes in seconds (all configurable in the render properties panel). I don’t think there’s a time limit of animations.
I can’t get this working with current Mixamo. I build the rig, export as fbx, and when I upload to Mixamo, it just appears as a solid mesh that doesn’t move.
Unfortunately, uploading a roblox rig with the mesh has never worked AFAIK. You need to export from Blender with only “Armature” selected, to get just a rig. The FBX will be about 24k. You’ll know it worked if, upon upload, you see a blue stick figure (the rig) doing a side to side looking idle animation. If the stick figure is immobile, or the upload hangs, something still isn’t right. Previewing animations is all stick man, so you don’t really know what you’ve got until the resulting Mixamo FBX is back in Blender.
Okay, it works that far. Then when I upload it to the rig in blender, first I get the error that there is no ‘active keying set’. So, upon adding one of those, I try again. And this happens:
So, you saw your uploaded rig animating correctly on the Mixamo site? There are two ways to bring apply the resulting downloaded fbx to your rig in Blender, “Import FBX” being the go-to one, where you just choose the downloaded file (after setting Keying Set to “LocRot”, as you’ve found already discovered). Normally, this results in seeing the imported animation on its final frame.
You can also use Blender’s built-in FBX import to import the file, which will make a second rig in your workspace. That can be applied to the roblox imported rig with the Map Keyframes by bone name option, but it’s also useful just to import it this way to sanity check that it has the keyframe data you’re expecting. And you can watch just the armature animate.