Install Asset
Install via Godot
To maintain one source of truth, Godot Asset Library is just a mirror of the old asset library so you can download directly on Godot via the integrated asset library browser

Quick Information

Adds the OBJExporter singleton, allowing to export and import models from OBJ format (.obj/.mtl files). Pure GDScript and works during runtime (not just in the editor) not requiring mono nor any GDExtension.
OBJExporter Plugin for Godot 4.x
Godot plugin to export and import meshes as OBJ (.obj
, .mtl
) from games and apps during runtime. Does not use any editor-only classes, and is pure GDScript (not requiring mono version nor any GDExtension shenanigans).
Based on the work of mohammedzero43's CGSExporter and fractilegames's godot-obj-export for the exporter, and includes a wrapper method for the ObjParse
class from Ezcha's gd-obj for importing.
How To Export Meshes
Install the plugin, activate it. This will make the OBJExporter
singleton available to your game/app.
To save a mesh to a .obj
/.mtl
file pair, call:
OBJExporter.save_mesh_to_files(mesh, file_path, file_name_without_extension)
So if you want to save the mesh in a my_meshinstance3d
node into user://model/my_file.obj
and user://model/my_file.mtl
, use:
OBJExporter.save_mesh_to_files($my_meshinstance3d.mesh, "user://model/", "my_file")
Important: the file_path
must exist, so check and create it with DirAccess
first, if needed.
Signals
Depending on model complexity, the file generation might take a good while, so it happens asynchronously. Does not use threads, instead it relies on await
to run in the background in the main thread.
Therefore, the OBJExporter
singleton has 3 signals to inform your application:
export_started
:
Emitted when save_mesh_to_files()
is called
export_progress_updated(surf_idx, progress_value)
:
Emitted periodically during file generation (every 60 vertices), to be used to update progress bars and similar. Arguments are surface index (starting at 0
) and a normalized progress value (that is, range from 0.0
to 1.0
) of that surface. There is no argument for overall progress value as calculating this would be unnecessarily costly.
export_completed(object_file, material_file)
:
Emitted when the process is completed and the files are saved to disk. The arguments are the final filenames used (e.g. user://model/my_file.obj
and user://model/my_file.mtl
), composed from the input arguments.
Since OBJExporter
is a singleton and therefore not visible in your scene tree in the editor, connect these signals via code (if used), e.g.:
func _ready():
OBJExporter.export_started.connect(_on_export_started)
OBJExporter.export_completed.connect(_on_export_completed)
OBJExporter.export_progress_updated.connect(_on_export_progress)
How To Import Meshes
To import a mesh from an .obj
file autodetecting the .mtl
file, call:
OBJExporter.load_mesh_from_file(file_path)
Or you can also manually specify the material file:
OBJExporter.load_mesh_from_file(obj_file_path, mtl_file_path)
This method is fully synchronous and will return the mesh (it is a transparent call to ObjParse.load_obj
).
Included Example Project
Included in the repo is an example project which exports the built-in mesh from a MeshInstance3D
node.
The exported .obj
/.mtl
, later imported into Blender:
Clicking Import Suzanne
will do exactly what it says on the tin:
Thanks to bananu7 for pointing me in the right direction on indexing vertices with SurfaceTool
.
Adds the OBJExporter singleton, allowing to export and import models from OBJ format (.obj/.mtl files). Pure GDScript and works during runtime (not just in the editor) not requiring mono nor any GDExtension.
Reviews
Quick Information

Adds the OBJExporter singleton, allowing to export and import models from OBJ format (.obj/.mtl files). Pure GDScript and works during runtime (not just in the editor) not requiring mono nor any GDExtension.