My Blender to Godot Workflow
I’ve streamlined my game development by using Blender custom properties and Godot @tool scripts to automatically transform 3D assets into functional game objects, allowing me to handle level design entirely within Blender.
My Custom Blender to Godot Workflow
January 13, 2026
Everything in my Godot scene comes from Blender! Everything!
For a while now we've been able to import .blend files directly into the Godot editor. This uses a behind-the-curtain .gltf import process to bring over mesh, animation, textures, etc. But what about things that don't come over from the .blend? What if I want to define things in Blender like what's considered an NPC object, what specific NPC dialog script it should use, what's considered a door, a drivable car.... What if I want to define specific car suspension or wheel friction properties for that car?
Need to exclude volumetric fog from an interior? Defined in Blender. Should this door open? Ask Blender! What camera to use for this NPCs dialog? Ask Blender what camera is parented. Which objects or lights will get baked lighting? It's defined in Blender! You get the idea.
A look at some of the custom properties I set up in Blender
I'm doing this through Blender custom properties. They come over in the Godot dictionary. The benefit is I can stay in Blender for the whole level design process and the scene setup and optimization is completely automated in Godot with my custom scripts in the editor and at runtime.
The main runtime processor that converts Blender objects into functional Godot game objects.
Here's an example! "TriggerProcessor" is my main runtime processor that converts Blender objects into functional Godot game objects. Here's how it works:
- It recursively scans all nodes in the scene via "_scan_node()"
- For each node, it checks for "extras" metadata (Blender custom properties)
- Based on property values I set up, it converts meshes into triggers, physics objects, NPCs, trigger zones, etc.
Here's a look at the Trigger Processor in action:
GDScriptCopy
func _scan_node(node: Node) -> void:
# Get Blender custom properties from "extras" metadata
var extras: Dictionary = {}
if node.has_meta("extras"):
extras = node.get_meta("extras")
# Check for specific properties
if extras.has("trigger-type"):
_convert_to_trigger(node, str(extras["trigger-type"]))
if extras.has("fog-exclude"):
_create_fog_exclusion_zone(node, extras)
# ... etcBut that's just runtime! That means it does this when the game starts. But what about things I need to see in the editor? For example let's say I want to define an area in blender for "fog-exclusion." This could be an interior where I don't want to see any environmental volumetric fog! I create a cube in Blender and set the custom Boolean property "fog-exclude" and set it to true.
What my fog exclusion zone object looks like in Blender. "Display as" is set to bounds.
My custom property in Blender for fog exclusion
That's great! Thanks to my "TriggerProcessor" in Godot that area will not have fog. There's one big problem though... Remember that was just a giant cube from Blender. At runtime that cube is converted to an invisible negative fog volume, but in the Godot viewport it also shows up as a giant cube. It hasn't been converted yet! This is a problem because I can't see my building in the editor. It's also blocking functionality like light baking that has to happen before runtime!
The fog exclusion zone is just a big cube in the Godot editor
So how do we solve this? I have two types of automatic processing in my Godot scene. The first, like TriggerProcessor, happen at runtime! These things don't show up in the editor. The second is a @tool script! Take this one for example. It's called "ZoneVisualizer."
Here's an example of a tool that runs in the editor!
- It runs in the editor (marked with @tool)
- Again, it checks "extras" metadata for trigger/zone properties (custom properties set in Blender)
- In this case it makes those meshes transparent, unshaded, shadowless so they don't interfere.
And here's the result in the viewport!
Now we can visualize the zone however we want in the viewport
In this case I made the zone a semi-transparent green, but we could really make that appear however we want! In the actual game it doesn't show up at all! It just excludes the volumetric fog from that area.
In the game itself we don't see a big green box.
Here's a look at the actual code in that zone visualizer tool for those that want a better look:
GDScriptCopy
if node.has_meta("extras"):
var extras: Dictionary = node.get_meta("extras")
for key in extras.keys():
var key_lower := str(key).to_lower()
if "trigger" in key_lower or "zone" in key_lower:
is_zone = trueSo that's a look at my custom Blender to Godot workflow. It's simplified, but now you see how I take two types of processors, and use them to automate my workflow. The first type works at runtime, and the second type works in the editor to give me new custom functionality and tools! It doesn't stop with simple zones though. I'm using this custom property Blender workflow for SOO many things! I'll name just a few that already work in the game:
- physics objects (assign to object in Blender and it gets physics in Godot)
- npc (assign to a rig and it gets npc dialog functionality)
- door (object becomes a door and gets special custom door logic I wrote)
- switch
- car (yep, drivable car complete with wheel and suspension properties)
I can even use custom properties out of Blender to define what's a drivable car
- enemy ai
- level transitions, save zones, spawn zones, etc.
- assigning different materials to surfaces to change the footstep sound
- which objects get light baking,
- which objects have shadows
- and so much more...
I hope that's sparked some ideas for you! This workflow is super flexible. I'm not even getting into the ways I've used it to optimize my game and help it run faster.
You might ask "why go through all this trouble in Blender. Why don't you just set all the properties in Godot?"
This system has two benefits. One, I keep my level design in Blender. For me, this is great because I have 15+ years of experience with Blender, and not nearly as much in Godot. The more of my game I can keep in Blender, the faster and more efficient I am! Second, this is about automation! The last thing I want to do is spend my time navigating Godot UI to hunt for little checkboxes. If I know I'm going to have 100+ doors in my game, it makes sense to do this work once, so all future door setup, scripting, animation, pivot point setting, etc. is completely automated.
As always, feel free to reach out with questions, and please consider supporting my game! I'm using open source tools and keeping info open as well. Now go use it on your game!