3DAssets.dev

Godot guide

How to import free 3D models into Godot

Godot 4 treats a GLB as a native scene, so importing one is a file copy. Here is the editor route, the runtime route, and how to set up collision and materials without fighting the reimporter.

3DAssets.dev4 min read

Of the major engines, Godot has the easiest relationship with glTF: it is the format the engine's own documentation points you at, and there is no importer package to install. A .glb in your project folder is a scene.

Everything on 3DAssets.dev is a self-contained GLB with the textures embedded, which is the case Godot handles best.

The editor route

Copy the file into your project, or drag it into the FileSystem dock:

1cp ~/Downloads/model.glb /path/to/MyGame/models/

Godot imports it as a PackedScene as soon as it appears. Drag it from the FileSystem dock into your scene tree and you have an instance, with its meshes, materials and animation player already set up. That is the whole process.

A useful habit: keep the downloaded files in one folder such as res://models/, and give each one a name that matches the asset it came from. The catalogue's slugs make good filenames, and future you will want to know which model a mesh came from.

Instancing from code

1# Godot 4: copy model.glb into res://models/ and the editor imports it as a scene.
2var packed := load("res://models/model.glb") as PackedScene
3var model := packed.instantiate()
4add_child(model)

load() here reads the imported resource, not the file on disk, which is why this works with no glTF parsing in sight.

Do not edit the imported scene

The one habit worth forming early. When you open an imported model and start renaming nodes or changing materials, you are editing a scene Godot regenerates from the source file, and a reimport wipes it. There are two supported places to make changes:

  • Instance the model in a scene of your own and change things there. Your scene owns the overrides and they survive reimports.
  • Use Advanced Import Settings, from the Import dock or by double-clicking the file. Settings there are written to the .import file beside the model and are reapplied on every reimport.

Advanced Import Settings is also where per-mesh options live: generating LODs, marking a mesh as a collider, and extracting materials to their own resource files if you want to edit them properly.

Collision

For a static prop, the fastest route is the naming convention Godot reads from mesh names in the source file. A mesh named with a -col suffix gets a StaticBody3D with a concave ConcavePolygonShape3D built from its triangles; -convcol gives a convex ConvexPolygonShape3D instead, which is what you want on anything dynamic. The -colonly and -convcolonly variants do the same but drop the visible mesh, which is how you author an invisible collider.

If you are working with a model you did not author, you cannot rename its meshes without opening it in Blender first. In that case either:

  • Open Advanced Import Settings, select the mesh and turn on physics, which produces the same result without touching the file, or
  • Instance the model into a scene, add a StaticBody3D and a CollisionShape3D alongside it, and give the shape a BoxShape3D or a convex shape sized to the model.

For most props the box is the right call regardless. A concave collider on a detailed model is a lot of physics cost for a crate nobody walks on top of, and Godot cannot use one on a moving RigidBody3D at all.

Animations

Models with moving parts arrive with an AnimationPlayer node and clips under their published names, so a supply crate has open and close and a fan has spin:

1@onready var anim: AnimationPlayer = $Model/AnimationPlayer
2
3func open_crate() -> void:
4 anim.play("open")
5
6func close_crate() -> void:
7 anim.play("close")

Looping is not set by the clip, so a spin you want running continuously needs the loop mode set on the animation resource, either in the Animation panel or in Advanced Import Settings, where you can mark a clip as looping without editing the imported scene.

Scale and orientation

Models on 3DAssets.dev are authored in metres with +Y up, which matches Godot's convention directly. A five-metre tree arrives five units tall, standing on the origin plane, so it needs a position and not a scale factor.

Godot's importer will offer to apply a root scale on import. Leave it at 1 unless you have a specific reason: a project where half the models have been scaled at import time is a project where nothing lines up and nobody can tell why.

Loading a model at runtime

load() only reads resources that were imported into the project at build time, so streaming a model from a URL needs the glTF parser directly:

1func load_glb_from_bytes(bytes: PackedByteArray) -> Node:
2 var doc := GLTFDocument.new()
3 var state := GLTFState.new()
4 var err := doc.append_from_buffer(bytes, "", state)
5 if err != OK:
6 push_error("glTF parse failed: %d" % err)
7 return null
8 return doc.generate_scene(state)

Fetch the bytes with an HTTPRequest node pointed at the model's CDN URL, then hand them to that function. Because the URLs on cdn.3dassets.dev are immutable, caching a downloaded file in user:// and checking there first is straightforward and worth doing.

This route matters if you are building something that pulls content after release. For a normal game, importing at build time is simpler and faster.

If textures come in blank

Textures in these files are WebP, carried by the EXT_texture_webp glTF extension. Godot 4 reads them, but if you are on an older build and a model arrives untextured while its geometry is fine, that extension is the first thing to check. Updating the engine is the fix; re-exporting the model from Blender with PNG textures is the workaround.

Next

Working across engines? Importing the same models into Unity covers the glTFast route, which is a little more setup than this. If you want an agent driving the editor as well as picking the models, Godot has several community MCP servers.

Common questions

Does Godot support GLB files?
Yes, natively and without a plugin. Godot 4 treats glTF and GLB as first-class scene formats: copy a .glb into your project folder and the editor imports it as a PackedScene you can instance like any other scene. It is the format the Godot documentation itself recommends for bringing models in.
How do I add collision to an imported model in Godot?
The simplest route is the naming convention: rename a mesh node with a -col, -convcol or -trimesh suffix in the source file and Godot generates a matching collision shape on import. If you cannot edit the source, use the Advanced Import Settings dialog to add physics to a mesh, or add a CollisionShape3D by hand in a scene that instances the model.
Why do my changes to an imported model keep disappearing in Godot?
Because you are editing the imported scene, which is regenerated from the source file every time it is reimported. Instance the model into your own scene and make changes there, or use the Advanced Import Settings dialog, which stores its settings in the .import file and survives a reimport.
Can Godot load a 3D model from a URL at runtime?
Yes, but not with load(), which only reads imported project resources. Download the bytes with an HTTPRequest and pass them to GLTFDocument.append_from_buffer, then call generate_scene on the resulting GLTFState. This is how you would stream models into a released game rather than shipping them all in the build.

Keep reading

Unity guide

How to import free 3D models into Unity

Unity does not read glTF out of the box. Install glTFast, drop the file in, and you have a prefab. Here is the setup, the render pipeline trap, and the one conversion textured models need.

AI setup

Give your AI assistant a 3D model library

An AI coding assistant can write a three.js scene in seconds and then fill it with grey cubes, because it has no models and no way to find any. Connecting it to a catalogue fixes that in one line.