"The FBX export recipe that actually works"
- Animated character imports with wrong orientation relative to your OBJ props (facing yaw constants break).
- Mesh scale looks right but animations are microscopic / gigantic.
- Clips missing from the vmdl, or one FBX dumps every action when you only wanted one.
Animated models need a different scale path than static OBJ: ModelModifier_ScaleAndMirror (0.3937 for cm sources), not per-file import_scale on the RenderMeshFile alone — import_scale leaves AnimFile data unscaled.
Blender meters → FBX writes raw centimeters (apply_unit_scale) → 0.3937 → engine inches. That is the citizen convention.
Export settings that diverge from the OBJ-path axes break facing constants you already tuned for props.
Blender FBX export (verified in-engine — orientation + scale match the OBJ path so facing-yaw constants stay valid):
| Setting | Value |
|---|---|
| Axes | default (forward −Z, up Y) |
bake_space_transform | True |
add_leaf_bones | False |
primary_bone_axis | 'X' |
secondary_bone_axis | 'Z' |
| Authoring units | meters |
| File format | Binary FBX (what Blender writes — required) |
Split exports:
- One FBX for mesh + skeleton —
bake_anim=False - One armature-only FBX per clip —
bake_anim_use_all_actions=False, active action only
vmdl scale:
ModelModifier_ScaleAndMirror { scale = 0.3937 }Do not rely on RenderMeshFile.import_scale alone for animated models.
Schema reference: addons/citizen/Assets/models/citizen/citizen.vmdl + prefabs/*.vmdl_prefab for AnimFile / AnimationList / BoneMarkupList. Keep default_root_bone_name = "pelvis"; pelvis is the true root; bone_cull_type = "None" to keep helper bones.
Author fade_in_time / fade_out_time on clips if you will enable crossfade-without-animgraph.
Matching OBJ export axes keeps the compiled bone/mesh frame aligned with static props, so one facing-yaw table works for both. ScaleAndMirror is applied to the whole model graph (mesh + anims + physics shapes), which is why citizen authors cm physics alongside 0.3937 instead of inch-scaling each stream independently. Per-clip FBX with bake_anim_use_all_actions=False prevents accidental multi-action dumps into a single AnimFile.