Skip to content

Blender → UE Skeletal Mesh Rig Transfer

Summary: How to take a mesh authored/rigged for one skeleton (e.g. a FAB/marketplace armor set on standard Mannequin) and re-rig it onto a different target skeleton (e.g. SK_Als) so it deforms correctly via leader pose. Covers the Blender reshape + weight-transfer pass, FBX export settings, and the MCP/Python import flow into Unreal — including the non-obvious traps that will silently break the result.

Table of Contents


When To Use This

Situation Use this?
Mesh rigged to Skeleton A, must deform on Skeleton B (different bone count / rest pose / spine subdivision) Yes
Mesh already on the target skeleton, just needs re-export No — straight export/import
Driving equipment that stays on its own skeleton at runtime No — use a UE IK Retargeter instead (per-frame cost, no re-rig)

Equipment that leader-poses off the player body must share the player's exact Skeleton asset — bone names matching is not enough; a different rest pose / bone hierarchy distorts. That is why re-rigging (not retargeting) is the chosen path for fixed body armor. See EquipmentVisualConfig.DeformingMeshes (Source/ProjectEternal/Public/EquipmentManagement/Data/EquipmentVisualConfig.h).


Pipeline Overview

 BLENDER                                   UNREAL
 ┌──────────────────────────────┐         ┌───────────────────────────────┐
 │ target body mesh + target rig│         │ delete old SK (if reskinning  │
 │ (weight source, e.g. SKM_Male3)│        │ an existing asset in place)   │
 └───────────────┬──────────────┘         └───────────────┬───────────────┘
                 │ align (pose rig to mesh)                │ fresh import (NOT reimport)
                 ▼                                         ▼  force target Skeleton via
 ┌──────────────────────────────┐  export  ┌───────────────────────────────┐
 │ 1. reshape armor → rig rest   │ ───FBX──▶│ FbxImportUI.skeleton = target │
 │ 2. transfer body weights      │          │ run on Slate post-tick (async)│
 │ 3. bind to target rig         │          │ reassign materials by slot    │
 └──────────────────────────────┘          └───────────────────────────────┘

Key principle: the armor's base mesh must sit in the target skeleton's reference pose, skinned with the body's weights. Everything below serves that.


Stage 1 — Blender: Reshape + Weight Transfer

The marketplace mesh is modeled in its source skeleton's rest pose. The target skeleton's rest pose differs, so the mesh must be reshaped before weights are transferred.

Step Action Why
Prep Apply Mirror and any generative modifiers; delete dead ones Weight transfer + export need final geometry
Align Pose the target rig (Pose Mode, never Edit Mode) so the body overlaps the armor Surface mapping samples current positions
Reshape Surface Deform on each armor piece → target body; bind while aligned; reset rig to rest → armor follows body into the rest pose; Apply the modifier Bakes the armor into the target rest pose, preserving bulk
Weights Data Transfer body → armor: POLYINTERP_NEAREST (Nearest Face Interpolated), by-name, use_object_transform=True Maps each armor vertex to nearest body surface; handles unit-scale differences
Bind Point each armor Armature modifier at the target rig Deform via target bones
Verify Pose the rig, render (OpenGL render works; screenshot tools hang in this project) Confirm deformation before export

Notes: - Pose Mode, not Edit Mode — Edit Mode changes the rest/bind and breaks existing weights. - Weights are per-vertex (pose-independent); only the mapping uses current surface positions, so alignment matters only at transfer time. - A bulky armor over a thin body is fine — Nearest-Face maps regardless of thickness.


Stage 2 — FBX Export

Recommended export_scene.fbx settings (UE-friendly):

Setting Value
use_selection True (select armature + the meshes for that piece)
object_types {'ARMATURE','MESH'}
add_leaf_bones False
bake_anim False
primary_bone_axis / secondary_bone_axis Y / X
apply_scale_options FBX_SCALE_NONE
axis_forward / axis_up -Z / Y

The armature OBJECT name becomes the skeleton's root bone in the FBX. Name it exactly what the target skeleton's root bone is called (UE Mannequin/ALS = root). See Critical Gotchas.

Group meshes per target SK asset (one FBX each). A combined-mesh FBX imports as one SK with multiple material slots.


Stage 3 — Unreal Import

Import is driven by Python (FbxImportUI), not the MCP native import or the MCP py console directly — both have blocking issues (see gotchas). The flow:

Step Detail
Capture Before deleting an existing SK, record its material slot → MaterialInstance mapping
Delete Delete the old SK asset (fresh import is required to set a new skeleton)
Import FbxImportUI.skeleton = <target>, import_materials=False, scheduled on a Slate post-tick callback
Materials Reassign MaterialInterface per slot from the captured mapping
Save EditorAssetLibrary.save_loaded_asset

References to the SK that are TSoftObjectPtr resolve by path, so delete + fresh-import to the same path relinks automatically — no reference repair needed. Hard (TObjectPtr) refs would need consolidation instead.


Critical Gotchas

Symptom Cause Fix
cannot merge bone tree with the existing skeleton / incompatible Skeleton FBX skeleton root doesn't match target. The armature object name becomes the root bone — root.036 exports a stray root_036 above the real bones Rename the armature object to the target root bone name (root); ensure a single top bone with pelvis/ik_foot_root/ik_hand_root as its children (not 3 separate roots)
Imported mesh keeps the old skeleton despite setting FbxImportUI.skeleton Reimport-in-place ignores the skeleton param — only fresh imports honor it Delete the asset first, then fresh-import
Property 'Skeleton' ... is read-only SkeletalMesh.skeleton cannot be reassigned from Python Must (re)import to change skeleton
New skeleton asset created instead of binding to target MCP native manage_asset import ignores the skeleton param Use Python FbxImportUI with skeleton set
Editor crash: Assertion failed: ++Queue(QueueIndex).RecursionGuard == 1 Heavy FBX import run synchronously inside the MCP py console handler → taskgraph re-entrancy Defer the import to unreal.register_slate_post_tick_callback (runs on a clean game-thread tick) — see [[reference_ue_async_import_slate_tick]]
Armor 100× too small/large vs rig in Blender Mesh authored in meters, rig at 0.01 (cm) scale; reassigning obj.parent via the data API drops the compensating matrix_parent_inverse Set obj.matrix_parent_inverse = rig.matrix_world.inverted() after reparenting
VB ... virtual bones in the target skeleton Engine-side bones; not exported from Blender, not needed in the FBX Ignore
MCP py returns no stdout Console output isn't captured unreal.log_warning('TAG ...') and read Saved/Logs/ProjectEternal.log — always read the log after a Python run

Scripts

Script Runs in Purpose
Tools/Blender/skeletal_rig_transfer.py Blender Reshape (Surface Deform), weight transfer, bind, per-group FBX export. Edit the CONFIG block.
Tools/Python/ue_skeletal_import.py Unreal (editor Python / MCP py) Async FbxImportUI import forcing a target skeleton + material reassignment. Edit the CONFIG/JOBS block.

Both are parameterized at the top (collection names, armature name, target skeleton path, FBX↔asset job list). They are skeleton-agnostic — set the target skeleton path for non-ALS rigs.


Worked Example: Knight Armor → SK_Als

Item Value
Target skeleton /ALS/ALS/Character/SK_Als (the player body SKM_Male3_Rigged uses it)
Source skeleton (wrong) SK_Mannequin — different spine subdivision → distortion
SK assets (reimported in place) SK_Knight_Helm, _Hands, _Feet, _BodyArmor, _Cloak
Material slots M_Knight19_NMI_Knight_N (1–4); Cloak only slot 4
Consumers EquipmentVisualConfig (Knight_BodyArmor/Feet/Hands/Helm), via soft refs — auto-relinked
Cloak note Exclude the low-poly cloth proxy; export the real cloak mesh only

Full session detail (incl. the crash + broken-asset recovery) is in agent memory project_knight_armor_als_rerig.


Source References

Scripts

Component Location
Blender reshape + transfer + export Tools/Blender/skeletal_rig_transfer.py
Unreal async force-skeleton import Tools/Python/ue_skeletal_import.py

Unreal

Component Location
Equipment mesh refs (leader pose) Source/ProjectEternal/Public/EquipmentManagement/Data/EquipmentVisualConfig.h


Recent Changes

Date Change Impact
2026-05-29 Initial doc — knight armor re-rig to SK_Als Establishes repeatable Blender→UE skeletal re-rig flow