Rigged characters are only as good as the pipeline that gets them into your engine. Export a skeletal mesh from Blender as a GLB file, import it into Godot 4, and hook up the AnimationPlayer node so every clip is accessible from GDScript — here's the full workflow, step by step.
Set up the armature and NLA editor in Blender
Before exporting, your rig needs clean animation data. Each distinct action — idle, run, attack — should live as a named Action in Blender's NLA Editor, stashed as an NLA strip.
![]()
Key steps in Blender:
- Select your armature object in the outliner
- Open the Action Editor (switch a viewport to Dope Sheet > Action Editor)
- For each animation, name it clearly:
idle,run_forward,attack_slash - Click Push Down to stash the action as an NLA strip
- Repeat for every clip
Naming matters — Godot will surface these names directly in the AnimationPlayer.
GLB export settings
In Blender's export dialog (File > Export > glTF 2.0 / GLB):
| Setting | Value |
|---|---|
| Format | GLB (binary) |
| Include > Selected Objects | ✓ (mesh + armature only) |
| Armature > Add Leaf Bones | ✗ off |
| Animation > Export NLA Strips | ✓ on |
| Animation > All Clips | ✓ on |
| Animation > Optimize Animation Size | ✓ on |
Disabling Add Leaf Bones prevents Godot from adding phantom tip bones that break IK chains.
# Blender Python equivalent (for batch scripts)
import bpy
bpy.ops.export_scene.gltf(
filepath="/path/to/character.glb",
export_format='GLB',
export_animations=True,
export_nla_strips=True,
export_all_influences=False,
export_optimize_animation_size=True,
export_leaf_bone=False
)
Import the GLB and connect AnimationPlayer in Godot 4
Drop the GLB into your Godot project's res://assets/characters/ folder. Godot auto-generates an .import file and creates an internal AnimationPlayer node containing all your NLA strips as animation tracks.
![]()
Import configuration
Select the GLB in the FileSystem panel, open the Import dock, and check:
- Animation > Import — enabled
- Animation > FPS — match your Blender timeline FPS (usually 24 or 30)
- Skins > Use Named Skins — enabled for readable bone names
- Meshes > Generate LODs — optional but recommended
Hit Reimport after any change.
Scene structure
Instance the GLB scene (Ctrl+Shift+A) into your level. The resulting node tree looks like this:
Character (Node3D)
└─ character_root (Node3D)
├─ Skeleton3D
│ └─ [BoneAttachments...]
├─ MeshInstance3D
└─ AnimationPlayer
Access the player via $character_root/AnimationPlayer or cache a reference:
@onready var anim_player: AnimationPlayer = $character_root/AnimationPlayer
func _ready() -> void:
anim_player.play("idle")
print(anim_player.get_animation_list()) # Debug: list all clips
Blending and transitions
Godot 4's AnimationPlayer supports crossfade blending:
# Crossfade from current to run in 0.2 seconds
anim_player.play("run_forward", -1, 1.0, false)
anim_player.queue("run_forward") # Loop without gap
# Or use AnimationTree for full state machine control
For complex character controllers, swap to an AnimationTree with a AnimationNodeStateMachine — but start with AnimationPlayer to verify all clips export correctly first.
Troubleshoot common export issues
Missing animations in Godot — check that all actions were pushed down as NLA strips before export. Blender only exports stashed strips by default.
Scale is wrong (100× too large) — your armature's scale isn't applied. In Blender, select the armature, press Ctrl+A > All Transforms to apply scale before export.
Bone names are Bone.001 etc. — rename bones in the Armature data properties before export; Godot cannot rename them after import without losing track references.
T-pose on first frame — add an explicit keyframe for all bones on frame 0 of your idle animation to prevent Godot interpolating from the rest pose.
Quick checklist before every export
- All actions named and pushed to NLA
- Armature scale applied (
Ctrl+A) - Leaf bones disabled in GLB export
- NLA Strips + All Clips enabled in GLB export
- FPS in Godot Import matches Blender timeline
- Reimport after any setting change
Once the AnimationPlayer is wired and anim_player.play("idle") runs cleanly, browse the 747 free game-ready GLB assets at BitSoul's marketplace — many include pre-rigged characters and props ready to drop straight into this workflow.
This post is part of the Ultimate Guide to Free 3D Game Assets — BitSoul's complete reference for formats, texturing, rigging, optimization, and engine integration.
Build with real assets: grab the 98-model Character Pack on the BitSoul marketplace and drop them straight into your project.