Full Roblox ↔ Blender Rig Animation Pipeline (Motor6D + Bone Compatible) IK,FK, IK/FK switching

This post covers setting up Blender rigs for Roblox animation export, including plugin setup, data transfer, resolving bone/motor6D mismatches, and building IK/FK control layers.

This tutorial demonstrates how to create a Blender rig specifically for Roblox animations, including workarounds for Bone/Mixed rigs to speed up your workflow and make it more customizable.
We’ll build a rig featuring:

  • IK/FK switching
  • IK/FK snapping (both ways)
  • Local and world IK controls
  • Improved leg IK
  • Custom controller displays

Example:



Jump to section:

Getting Started
Rigging
Transferring Existing Rig
Aligning Bones
Animating
Exporting
IK/FK Controls
IK-FK snapping ↔
Customizing bone look :t_shirt:
Hiding controls with zero influence
Character appearance

Cheat Sheet in Blender:

  • A select all
  • Shift+D duplicate
  • ESC cancels movement/rotation/scale and brings it back to original transform
  • Ctrl+P parent
  • Alt+P clears parent, move to armature root
  • Ctrl+Shift+C set bone constraints
  • Ctrl+A apply settings
  • Ctrl+S save
  • X/Y/Z lock current transformation method to axis
  • Shift+(X/Y/Z) lock current transform to any axis but pressed
  • G move
  • R rotate
  • S Scale
  • N open/close viewport menu

Terminology

  • I use “OS_” a lot. This refers to bones that directly influence Weight Painted bones (Weights)
  • “Proxy bones” bones that influence other bones
  • “Offsets” like proxy bones but influence (offset) pivot point (referred as OS_)
  • “Weights” original bones that have influence over topology (generated by plugin in this case)

Ready rig for impatient people:

Getting started

Getting started
  1. You need to get this Roblox plugin (free)
    https://create.Roblox.com/store/asset/16708835782/Blender-Animations-ultimate-edition
    Blender rig exporter/animation importer - #1628 by CAUTlONED - Community Tutorials - Developer Forum | Roblox

A part of my tutorial became outdated as I was writing it. You may view it, but it’s recommended to use the new method.

Outdated
  1. Make sure to get the code from pastebin
    image
    image


    Ctrl+A and then Ctrl+C that.

  2. Create a .txt file on your PC.
    image
    Paste all the code inside it and save.

  3. Now make sure you have display extensions enabled!
    https://fileinfo.com/img/help/windows_10_file_name_extensions_checkbox.png

  4. Now change .txt into .py

Review: RBXMonkey - Roblox Importer/Exporter — Blender Extensions

  1. Make sure you have Roblox Studio plugin installed!

  2. In Blender:


    image

    Locate the file you just created and open it
    image
    Now you should see this:

    (Press N if you don’t)

  3. Now for rigging, you also recommended to install this plugin: GitHub - waylow/boneWidget · GitHub


    image
    And install it the same way as you did with the previous plugin (this time select boneWidget.zip) though
    No need to unpack .zip :warning:

  4. IK-FK Snapping Tool

  5. Done! Plugins are set up!

Rigging

Rigging

I will explain the steps for when you have already rigged a working rig with weights in Blender and when you start with a fresh, entirely new rig.

Only if your rig is Bone/Mixed! :warning: ignore this instruction otherwise! :warning:

Problems: you can’t export a rig with bones really, you can only export the ones with a Motor6D hierarchy.

Solution: create a separate rig for exporting into Blender or importing animations into Roblox.
This can be generated automatically through this code snippet (make sure to select the mixed/bone only rig you want to convert into a pure Motor6D hierarchy)
Then paste this code into the console:

local Selection = game:GetService("Selection")

local rig = Selection:Get()[1]::Model
local new_name = rig.Name.."__Animation"

local ___ = workspace:FindFirstChild(new_name)
if ___ then
 ___:Destroy()
end

local new = rig:Clone()
new.Name = new_name

local function Recursion(target:Bone,parent:Part?):Part
 local point = Instance.new("Part")
 point.Size = Vector3.new(0.05,0.05,0.05)
 --point.CFrame = target.WorldCFrame
 point.Name = target.Name
 local motor = Instance.new("Motor6D")
 motor.Name=target.Name
 motor.Part0=parent
 motor.Part1=point
 motor.C0=target.CFrame

 Instance.new("Highlight",point).Name="DisplayHighlight"

 for i,v in target:GetChildren() do
  if not v:IsA("Bone") then continue end
  Recursion(v,point)
 end
 motor.Parent=point
 point.Parent=new
end

for i,v in new:GetChildren() do
 if not v:FindFirstChildOfClass("Bone") then continue end
 for ii,vv in v:GetChildren() do
  if not vv:IsA("Bone") then continue end
  Recursion(vv,v)
  vv:Destroy()
 end
end

new.Parent=workspace
Selection:Set{new}

Select your rig and press Export


Go to the Blender now:

Select the file you exported.
Now it will create a bunch of mess, probably.
Make sure to select “__RigMeta” in Outliner (Like Roblox Studio Workspace of Blender)

Go to Rbx Animations (Press N if you don’t see it)

Press Rebuild Rig

:warning: DO NOT DELETE __RigMeta, it contains IMPORTANT information for export! :warning:

You can already go animating it, but if you have the original Blender file of this model, I suggest looking at this step:

Transferring already existing, valid Blender rig

Transferring already existing, valid Blender rig

Make sure your original model’s skeleton is named “Armature” and the one you imported is “Armature.002”
Credit to ChatGPT for writing this code snippet btw.

import bpy  # Blender Pythoughn API

# Names of your armatures
source_name = "Armature.002"  # Plugin-generated skeleton
target_name = "Armature"      # Your cleaned/fixed skeleton

# Get the source and target armature objects
source_arm = bpy.data.objects.get(source_name)  # Source armature object
target_arm = bpy.data.objects.get(target_name)  # Target armature object

# Check if both armatures exist
if not source_arm or not target_arm:
    raise Exception("Check that both armatures exist in the scene with exact names.")

# Loop through all bones in the source armature (Edit Bones)
for bone_name, src_bone in source_arm.data.bones.items():
    
    # Try to find a bone with the same name in the target armature
    tgt_bone = target_arm.data.bones.get(bone_name)
    
    # Only copy if the bone exists in the target
    if tgt_bone:
        # Loop through all custom properties of the source bone
        for key in src_bone.keys():
            # Skip Blender internal metadata
            if key != "_RNA_UI":
                # Copy property value from source bone to target bone
                tgt_bone[key] = src_bone[key]

print("✅ Custom properties successfully copied from plugin skeleton to fixed skeleton!")

Now go to a Scripting workspace

  1. Create a new script
  2. Run the script

Ok, we have given the original mesh important metadata so the exporter can recognize it :fire:
ALSO THEY BOTH HAVE TO BE UNDER SAME COLLECTION* (just move them to Scene Collection just to be safe)

Althoughugh bones may still be incorrectly positioned.

Aligning bones :warning: skip if you want to use imported mesh :warning:

Aligning bones

Make sure your original model’s skeleton is named “Armature” and the one you imported is “Armature.002”
Running the script below makes bones with the same name align correctly.
Prior to running that make sure rigs are in the same position and face the same direction.
(Can be done with the use of 3D cursor and well geometry itself) Shift+S combinations and pivots, etc.
Etc select the same face in the Original mesh


(with all objects of Armature and including the armature itself selected)

Now select the same corresponding face in the imported object (will be triangulated most likely).
So select the whole object in the exported mesh (A key) and press Alt+J
Now you can select the corresponding face and move the 3D cursor to it


Now select all Original mesh objects( with armature) and do Shift+S → Selection to Cursor

You most likely will have to rotate original mesh aswell for it to work, DO ROTATE SKELETON ITSELF ASWELL*

Now, while you have original stuff selected, press Ctrl+A

Now you can run the code freely to align the bones itself:

import bpy

# Names of the armatures
source_name = "Armature.002"  # plugin armature
target_name = "Armature"      # your main armature

source = bpy.data.objects.get(source_name)
target = bpy.data.objects.get(target_name)

if not source or not target:
    print("One of the armatures was not found")
else:
    # Enter edit mode for both armatures
    bpy.context.view_layer.objects.active = target
    bpy.ops.object.mode_set(mode='EDIT')
    target_bones = target.data.edit_bones

    bpy.context.view_layer.objects.active = source
    bpy.ops.object.mode_set(mode='EDIT')
    source_bones = source.data.edit_bones

    # Switch back to target as active
    bpy.context.view_layer.objects.active = target
    bpy.ops.object.mode_set(mode='EDIT')

    for bone_name in source_bones.keys():
        if bone_name in target_bones:
            s_bone = source_bones[bone_name]
            t_bone = target_bones[bone_name]

            # Copy transform data
            t_bone.head = s_bone.head.copy()
            t_bone.tail = s_bone.tail.copy()
            t_bone.roll = s_bone.roll
            t_bone.use_connect = s_bone.use_connect

            # Match parent
            if s_bone.parent and s_bone.parent.name in target_bones:
                t_bone.parent = target_bones[s_bone.parent.name]

            print(f"Copied bone: {bone_name}")
        else:
            print(f"Bone {bone_name} not found in target")

    bpy.ops.object.mode_set(mode='OBJECT')
    print("✅ Bone transforms copied from Armature.002 to Armature")

Now you can entirely delete all imported objects except __RigMeta and keep using the Original mesh.


You might also want to set the pivot of everything into World Origin as well

Animating

Animating

Well, animating is dead simple.
Basic setup:

Have a Timeline window at the bottom:


60 = 1 second
120 = 2 seconds, etc.
Just make sure that the output has 60 FPS set
image

Let’s make 1 1-second looped animation, for example:

Set Start at 1, End at 60
image

Ctrl + Middle mouse drag at the timeline to zoom in/out, Shift + Middle mouse to pan the timeline.

I = set keyframe
A = select all

So what we want to do (In pose mode with armature selected) is to press A and then press I
To ensure everything is set.
Alt+R, Alt+G, Alt+S resets the Rotation,Position, and Scale of the selected bone. Scale obviously will not get exported since Roblox does not support it for now.

You may also want to toggle auto keyframing
image
Well rest are pretty obvious if you ever were animating inside a studio and knew Blender a tiny bit.

Exporting

Exporting

Very simple, pretty much

Make sure it’s the right armature and press Export Animation.

Move into Roblox Studio now:

Press Import Animation + press Ctrl+V


Press Save Animation to Rig

Open it with Roblox’s Animation Editor.


Press OK

IF YOU HAVE A BONE/MIXED RIG DON’T PANIC!!! :warning:

You just have to save the animation and then play on your rig, and it will all work fine. DON’T WORRY.
You might also just move the animation to a regular rig and play it.

Does it work fine on our non-animation import rig?

Just don’t EVER TRY to import animation into your mixed/bone rig directly, trust me, it will not work.

If you followed every step, your animation should now perfectly import into Roblox Studio. If something breaks, it’s usually a rig metadata issue - revisit the transfer script section.

Building rig controls (IK/FK)

Building rig controls (IK/FK)

Goal: Create a functional, Roblox-export-friendly rig with both IK and FK support, without breaking bone weights or export hierarchy.
We’ll separate bones into collections (“Weights”, “Offsets”, “FK”, “IK”) to safely edit pose behavior and fix IK instability.

Tutorials I took inspiration from:

https://www.youtube.com/watch?v=jIwrswJEFBQ
https://www.youtube.com/watch?v=suP14lYWpN8

Ok, so we have a rig:

And it is just horrific, but with a few changes, we can turn this into a nice-to-use rig with both IK and FK enabled and nice controls.

  1. Enter Edit mode
  2. Press A to select everything
  3. Press M → New Bone Collection → Name it something like “Weight” or “Defform”
  4. image
    You should be able to see this group now
    image
  5. Go back to viewport → Shift+D → ESC key
  6. Press M → New Bone Collection → “Offsets”
  7. Hold Alt + Click checkmark to disable Deform
    image
  8. Run this script:
import bpy

obj = bpy.context.object

if obj is None or obj.type != 'ARMATURE':
    raise ValueError("Select an armature object first!")

# Make sure we are in edit mode
if bpy.context.mode != 'EDIT_ARMATURE':
    raise RuntimeError("You must be in Edit Mode for bones!")

for bone in obj.data.edit_bones:
    if bone.select:  # only remove props from selected bones
        keys_to_remove = [k for k in bone.keys() if k != "_RNA_UI"]
        for k in keys_to_remove:
            del bone[k]

        if "_RNA_UI" in bone.keys():
            del bone["_RNA_UI"]

        print(f"Removed all custom properties from bone '{bone.name}'")

Make Weight/Deform hidden for now
image

So what we just did is we got the ability to “Offset” joints without breaking export.
Essentially, we will create a “helper” bone to adjust the center, make the IK solver work properly, and such.

Now, with all of “Offsets” selected, press Ctrl + F12 (Batch Rename)
Build that configuration and press “OK”


NOTE THAT YOU SHOULD SET Objects → Bones
Shift+S → Cursor To World Origin (1)

Create a bone Shift+A
Select the bone, press F2, and name the bone “Root”
Disable the deform in this bone
image

Select OS_LowerTorso (or highest-priority bone in the hierarchy besides HumanoidRootPart)
Then Ctrl + Select Root in Outliner

Move the cursor to the viewport and press Ctrl+P → Keep Offset
Now select just Root, without anything else and then Ctrl + Select HumanoidRootPart in Outliner
Move the cursor to the viewport and do Ctrl+P → Keep Offset again.


Now go from Edit Mode → Pose Mode
Hierarchy should look like this:
image
It will be a very boring but very essential part now.

Unhide Weights group
image

Now you need to “connect” every bone to make the Weight collection essentially follow every move of the Offsets collection.

Start from the head up to every limb.

Select OS_Head and then Shift + Select Head in viewport
Press Ctrl+Shift+C and select “Copy Transforms” constraintimage
Repeat this step for every bone, yeah, I know it’s annoying. Firstly, select bones with the “OS_” prefix and then corresponding ones without that prefix.
Well, the bones that have OS_ version counterpart obviously.
Once you have done that, you can hide the “Weights” group indefinitely and never ever suffer from using it
image

Now setting up proxies aka allowing you to move joints peasefully.

Get back into edit mode:

  1. Press A and deselect “Root” (Shift+Click in viewport)
  2. Press Shift + D and then press ESC
  3. Press Ctrl + F2

    Press “OK”

Again suffering (I’m sorry)
Starting from the head, Select OS_Head and Shift + Click on it again to select Proxy_OS_Head
Then press Ctrl+P, Keep Offset
Repeat so for every other bone

You will have something like that:

Now go through each OS_ without Proxy_ prefix and press H on them to hide since they are no longer needed to you.

Now we get that setup where we can finally edit joints, althrough we wont be really editing anything but tails of bones for them to be working with IK more correctly.


Select Head of RightLowerArm (Proxy_OS_RightLowerArm) and move 3D cursor to it

Select Tail of RightUpperArm (Proxy_OS_RightUpperArm) and move it to the 3D cursor.

Now repeat this step for the Left Arm as well, and EVERY bone, basically all tails must be connected to the heads.
DON’T MOVE HEADS, just tails, OK?

Result:

Why all this suffering?

Good damn question, and the answer is simple:
IK solver in Blender would freak out otherwise, and if we did not go through all this “hell” of creating “proxies”, then export would’ve been malformed or completely broken.

Firstly, we will create IK because how are we gonna make FK without being insane from IK first? :thinking:

  1. Select all (A key) and deselect Root (Shift+Click on Root bone)
  2. Shift + D and then the ESC key.
  3. M → New Bone Collection → “IK”
  4. Ctrl+F2

    Press “OK”
  5. Go to Pose Mode (suffering_again.exe)

    Guess what?
    Too bad, hidden bones in Edit mode and Pose mode don’t sync up!
    You have to hide non Proxy_ bones inside the Offsets group all over again :skull:
    For now, hide the IK group image
    And well hide bones from Offsets that don’t have Proxy_ in their name like you did before.
    Now unhide IK image

Now you must make bones from IK influence Offsets

Select IK bone, then Shift Select corresponding Offset bone and Ctrl+Shift+C image

Do it for every bone on joints (etc., Limbs, Arms,Legs), you don’t need to do anything with Head or Torso, really, and in fact, we will remove these bones in IK.

Now you can hide the Offsets group and go back to edit mode
image
Delete IK Head,UpperTorso,LowerTorso bones

Select Upper Legs and Parent them into “Proxy_OS_LowerTorso” (select Proxy_OS_LowerTorso as last target) and Ctrl+P Keep Offsets.

Now Parent Upper Arms and Parent them into “Proxy_OS_UpperTorso”


Now hide them.

Select heads of LowerArms and LowerLegs now


Extrude them this way:
E + Y + -1 in my case

Rename them into corresponding “IK_Leg_Pole_L” etc
IK + Limb + Pole + Side L/R

Parent them to Root now


Move them like that:

Select tails in leg Poles and move them forward:

Now we need to create arm and leg IK Controllers.



image

Name them accordingly “IK_Control_Arm_L”, etc

Select these bones now:

Shift+D and then ESC
Ctrl+F2 →
Press “OK”
Press Alt+P → “Clear Parent”

Go to pose mode now
Select IK_LeftLowerLeg
Ctrl+Shift+C and then press I
image


And oops, as we can see bone well “BROKE”

How to fix, you may ask?

Dead simple :skull:

We copied “TEMP_” bones for a reference
Go to image
image
Now rotate the Pole angle until the 2 X meet
image

The perfect pole angle for me was -90


Repeat the same steps for the other leg, but with the corresponding pole target and control

Now go to IK_LeftLowerArm.

And repeat such steps with corresponding controls.

You can go to the top view to adjust it more carefully:
I also recommend hiding some limbs at the bottom so their “X” axis does not disrupt you
44.8449 worked for me, and 135.155 (180 - 44.8449) for the other arm

Now IK is semi-done

You can disable axes
image

Go to edit mode:

Select all controls


Select Root and Press Ctrl+P → Keep Offset

Delete temp bones now, they are not needed anymore
image

Select Hands and Foots and parent them to their controls (Ctrl+P), select Hand and then Controller, etc



Go back to pose mode:
Select IK_LeftHand (NOT CONTROL BUT HAND ITSELF)
Ctrl+Shift+C copy location

Repeat the similar process for the other arm and legs

Uh oh, IK doesn’t work because bones are “too flat”
Solution? More annoying “proxy” bones :innocent:
Go back to Edit Mode and press Alt+H to unhide bones
And select these bones afterwards:


Press Shift+D and then ESC
Ctrl+F2 →
Press “OK”

Now Parent corresponding IK to Their Proxy Etc IK_LeftLowerArm to Proxy_IK_LeftLowerArm

Get back to edit mode and remove the Inverse Kinematic constraint from Originals like IK_LeftLowerArm, but keep it for their proxy

Get back to edit mode and hide on H these 8 bones for which you just created a proxy, do keep the proxy though

Select these two joints on the arms and drag them back a little

Do the opposite on the legs and drag them forward instead



(Make sure that Proxy_IK_LeftUpperArm and Proxy_IK_RightUpperArm are parented to Proxy_OS_UpperTorso)

So IK is already done pretty much, but in this tutorial, there will be an addition for the pole vector on the legs:

Select these heads on bones:


Extrude them down on the Z axis

Move 3D cursor here:

Shift+D + ESC bottom bone that we just created via extrusion and move it to the 3D cursor

Repeat it for the other leg as well
Now select both of these “Middle points” we just created, name them “Medians_L/R” and parent them to the Root bone.


Parent bottom, we just extruded into their representing control and named them “Bottom Point_L/R”


Rename the ones on top into “Top Point_L/R” (optional)

Parent Poles on legs to medians now

Hide these non-proxy bones now

Select the bottom one and then the middle one
and press Ctrl+Shift+C image
Set influence to 0.5


Now select the top one and then the middle one

and press Ctrl+Shift+C image
Reorder them to swap places (drag this slider image)

And now select the bottom one and then the middle one again
and press Ctrl+Shift+C image

Now repeat these steps for the other leg aswell and IK is finally fully done!

Adding FK

  1. Hide IK and unhide offsets
    image

  2. Press Alt+H

  3. Hide all non-proxies and Head with Lower torso KEEP UPPER/LOWER TORSO (proxy) NOT HIDDEN(note that some non-proxy bones are hidden under proxy bones, so double-click proxy bone to see if something is underneath)

  4. Select all (Press A) DO MAKE SURE TO UNSELECT ROOT AND UPPER TORSO and press Shift+D → ESC

  5. Press M → New Bone Collection → “FK”

  6. Press Ctrl+F2 →


    Press OK

  7. Now parent Upper Arms (ALL FK ones) to Proxy_OS_UpperTorso and Upper Legs to Proxy_OS_LowerTorso


    (Hide/Unhide Offsets temporarily if you need to select the proper FK bone)
    image
    Unhide them once everything is finished, thoughugh

Ok, FK is done, but it’s time to make the rig actually follow FK, so go to pose mode

Now select each FK bone, then Shift Select corresponding Offset bone and Ctrl+Shift+C image
Must be something like this if done correctly:


Well, repeat this for EVERY FK bone! (yeah boring I know)

Well, now FK is done!

Controlls & Settings

Temporally hide FK
image

Go to Edit Mode

Select the end of each limb:

Press Shift+S → Cursor To Selected


Set this setting now

Press Shift+D → ESC
M → New Bone Collection → “Drivers”
S → X/Y (depends, but it’s usually X) and move it a part a little bit

Parent them to the hands and foot now (to the corresponding ones)

And name them Something like Settings/Configs ANYTHING
My format will be “Config_Arm/Leg_L/R”


ALL WORK IN EDIT MODE IS DONE NOW :partying_face:
Go to Pose mode.
Hide everything but IK

Press Alt+H

Now hide EVERYTHING but poles and IK Controls


Hide everything but drivers and remove ALL constraints they have


Bring back offsets and IK


Make sure you only use proxies inside limbs of Offset (OS) and hide non-proxy limbs in Offset
Should look like this:

Select our config now



And repeat it for every Config bone we just made
Name could be any, but IK->FK makes the most sense since 0 = IK, 1 = FK
You can change it to Boolean as well if you want to control either full IK or Full FK (recommended)
In that case, naming it “FK?” would make more sense

After creating this property for each config right-click it
image

Select corresponding chain (green bones)


Locate FK property

Right-click the Influence Bar and paste the driver image
Repeat this for each limb DO COPY A NEW DRIVER THAT CORESPONDS TO A LIMB FROM CONFIG*

Oh, and yeah, after all that, do change mode to Individual Origins of Median Point

Now select all of the green bones and hide them


And enable FK

Do make sure this area has ONLY proxy bones and nothing else
image

Now?
Almost everything is set up, and soon we can customize bones!

Select Proxy_OS_LowerTorso and shift select any IK Control
Ctrl+Shift+C Child Of

Repeat it for the other Leg now

Repeat it for arms now, but select UpperTorso now instead of LowerTorso, and apply this to the pole as well

We essentially made an option for IK Control to follow the character
Time to add a toggle option!

Create Custom Property Follow IK Control (and turn it off or set to 0)
image

Create this property for each config bone.

Now, hover the cursor over the checkmark of this property, right-click, and copy it as a new driver
imageimage
Go to the green corresponding to the config bone and paste it inside the bone constraint’s influence

And repeat it, in case of arms, do include the pole as well

IK-FK snapping ↔

IK-FK snapping ↔

Remember me saying that we won’t be working with Edit mode? Well, too bad it was a lie, muahhahah
Go to edit mode
Select all poles and controls


Shift+D and ESC
Ctrl+F2

Press “OK”
Remove them from IK (Alt+Click)

Assign them to FK (Alt+Click)
image
Hide everything but FK

Parent them to corresponding bone (on both legs and arms), basically to LowerLeg/LowerArm


Go to pose mode and remove all bone constraints from them (green bones shall turn gray)


Hide TARGET_ bones

Unhide bone collections

Go to the IK-FK Snap plugin
image
Starting with the Left Arm
image
First 3 fields are pretty self-explanatory
image


image
Next 3 fields are exactly the same but replace FK with IK (Yes Real IK_ NOT PROXY_IK bones)
image


image
You already know where it is going



image


In these 2 fields, type “TARGET_” and find a corresponding Pole/Control (same name as in the previous 2 fields but with prefix TARGET_)

Now?
Repeat it for the other arm and legs, and your IK-FK snapping setup will be completed!
Leg example:

It works great to FK from IK, but may break a little from IK to FK.


Optional:
Pin this menu:
(right click)

Customizing bone look :t_shirt:

Customizing bone look 👕

Select a bone/bones:
Go to the rigging tab
image


Select a shape (cube in our example)

Select a color (Lime in our example)

Now press Set Bone Color and Create

Adjust visual



Press this button if there is an opposite a corresponding opposite side:
image

Now, you ideally should customize the look of everything.

Here is my example:


See how our rig became more “readable”?
Let’s expand it further by making non-relevant controls invisible:

Hiding controls with zero influence

Hiding controls with zero influence

Copy “FK?” driver


Select IK Control (green cube in this case)


image
Paste driver into the “Hide” property

If we are in FK mode, the cube should disappear.
Make sure to paste this driver into the IK pole of this limb as well

Now select the same joint’s any FK bone (blue ring in our case)

And paste it into their hide property


Right-click that hide property and Edit Driver

image
In that expression, add “1-” as a prefix
image

Should make our ring visible if we are in FK mode.
Now copy that driver and paste it into other FK bones in this limb, repeat these steps for other limbs aswell.

FK mode on all limbs:

IK mode on all limbs:

Character appearance

Character appearance


Go to object mode
Select the face object and Shift+Select the head

Press Ctrl+J

Done! Face should work now
image
image
You can also just export the rig as .gltf and reconstraint it back to follow the armature, keeps UV and texture that way.




Select a common vertex in the upper torso, for example
And move a 3D cursor to it

Select all imported new rigs and set their Pivot to the 3D cursor

Select original rig and move 3D cursor to a corresponding vertex

Delete “Rig” object (Keep insides thoughugh!)
image
Select our imported rig and snap it to the 3D cursor now

Delete original rig

Select the imported rig and get rid of the “.001” suffix by pressing Ctrl+F2 and setting that:

Now you need to constrain it to the armature, but luckily, we can run this script instead (make sure armature is named “Armature.001”
Do make sure to select ONLY imported rig body parts

import bpy

armature_name = "Armature.001"
armature = bpy.data.objects.get(armature_name)

if not armature or armature.type != 'ARMATURE':
    raise ValueError(f"Armature '{armature_name}' not found or isn't an armature.")

# we'll store the previous active object so we can restore it later
prev_active = bpy.context.view_layer.objects.active

for obj in bpy.context.selected_objects:
    if obj == armature:
        continue

    bone_name = obj.name
    if bone_name not in armature.data.bones:
        print(f"Bone '{bone_name}' not found in '{armature_name}'. Skipping '{obj.name}'.")
        continue

    # make object active (required for operator)
    bpy.context.view_layer.objects.active = obj

    # create the constraint
    constraint = obj.constraints.new(type='CHILD_OF')
    constraint.name = f"ChildOf_{bone_name}"
    constraint.target = armature
    constraint.subtarget = bone_name

    # update so transforms are correct
    bpy.context.view_layer.update()

    # set inverse using correct operator
    bpy.ops.constraint.childof_set_inverse(constraint=constraint.name, owner='OBJECT')

    print(f"Added Child Of constraint on '{obj.name}' → bone '{bone_name}'")

# restore previous active object
bpy.context.view_layer.objects.active = prev_active

OPTIONALLY, you could also run this script to strip away unneeded data that came from Roblox’s export

import bpy

for obj in bpy.context.selected_objects:
    # Remove all custom properties
    keys_to_remove = [k for k in obj.keys() if k != "_RNA_UI"]
    for k in keys_to_remove:
        del obj[k]

    # Also remove the _RNA_UI dictionary if it exists
    if "_RNA_UI" in obj.keys():
        del obj["_RNA_UI"]

    print(f"Removed all custom properties from '{obj.name}'")

OPTIONALLY, you could also clean up your file size by deleting unneeded materials. DO SAVE FILE BEFORE DOING THAT TOUGH!


And delete everything but “Material_0.001” or whatever material import created
image
Now select the armature and go to pose mode, you can now save the file and enjoy animating. The rig is completed!

For clothing UV, i recommend you look at this tutorial, it’s not related to this post much, but will be useful incase you make a custom rig.

Classic Clothing UV Mapping Guidelines[R15] - Community Resources - Developer Forum | Roblox

Thank you for following my tutorial!
Goodluck!

44 Likes

My biggest tutorial so far

Took a really long time to write


I will add add <details> thing rn and jump to section since i had to upload the post in order for it to work.

I will also make post in Resources > Community Resources with rig that you supposed to make acording to this tutorial.

2 Likes

Thanks for writing this. I always struggle to create animated characters and would like to be able to rig their meshes, instead of using Motor6D & Welds on their limbs and stuff. It would be good if your example was a character with limbs as I think it would have been easier to understand. Or perhaps I am missing something, which is more likely the problem :slight_smile:

You mean weights?
If it’s weights, then you can use this tutorial, although you probably need to have the original sample file with weights painted.

1 Like


Uh?

I don’t know how you have built hierarchy in Blender, so I can’t say much.
Probably the ChildOf modifier is improperly set.