-
-
Notifications
You must be signed in to change notification settings - Fork 21.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Godot 4.0 GLTF Importer missing "instanced sub-scenes" storage option from 3.4 (important for asset packs etc.) #56312
Comments
Do you think you can make a proposal for an 3d import toggle to: Godot 4.0 store individual objects as Meshes, but this needs to be enabled for the entire scene, and the file path needs to be set to a folder. |
From the point of view of the gltf2 importer it sends a node tree to the scene system. Since it can't write to the file system at this point there's no way to do missing instanced sub-scenes here by design. From the scene import system we want to propose a feature enabled for the entire scene where each mesh is saved, and the file path needs to be set to a folder. This is after auto LODing, collision generation, post import scripts and other processes. |
I just bumped into this and noticed, it seems atm that importing gltfs in 4.0 alpha there isn't a way to set meshes automatically to be exported as individual files after import? This would be extremely useful, for instance, allowing us to do wardrobe systems for the mesh files, systems that allows us to easily load meshes to do a armor change or weapon part change, similar to this: I would think this is related to this issue, pointing a folder or allowing it by default to create a folder with the name of the gltf, and inside separate what the user wants, in the case of meshes they could use the naming that comes from blender already. |
Anything that creates dependencies introduces what I call the ".material" problem from godot 3. There's a multi step reproduction case that cause flaws. Will need some new approaches. |
Well, some type of dependencies are good I suppose, you update the source and all dependencies are updated as well. If you are not meant to touch some kind of instanced data we could block it or warn that might break linked content. Just to contextualize this is a big problem in blender right now with the asset manager as well. I wouldn't mind if godot used it's own naming convention to automate some import functionality, right now this is a problem for me not being able to automatically import all meshes to individual files into a folder, preferable named to it's .gltf source. |
This can be done in the Advanced Import Settings dialog on the Meshes tab. You can save individual Mesh resources to |
I see, yea it works, still it would be pretty nice if this was possible to be done with all meshes from a .gltf automatically from a single tickbox, the names would be gathered from the source, ak blender's mesh data name, currently as you mentioned, one have to select all meshes tick save to file, and you have to type a name, otherwise it save as .res by default, tested it. Maybe we can do that through import scripts? Although I am sure in later versions of 4.0 we will have something for this, many people want to import various assets bundled together, having automatically they being split is a must, something to look in for in the future I guess. |
This issue is directly linked now to this problem #28275 regarding the issue on how keep custom tracks on imported animation tracks, as a workaround one can develop tools to edit animations after import, an example of needing custom tracks would be creating footsteps sounds, which are easily done from the animation player using call tracks. I guess should be worth mentioning this as well: godotengine/godot-proposals#4296 (comment) |
The animation library feature was merged recently to solve animation editing troubles. |
I also used instanced sub-scenes in 3.5. Since they aren't supported (yet) I just created a post-import script to handle it. Seems to work fine for both GLB & Blender import.
BTW Godot devs, I just started with the Godot 4 beta today and I'm loving the control in the 3d model importer dialog. And the direct .blend import. Thank you! |
I didn't know this was possible, but I managed to port the above c# script by @Geekotron to GDScript and it works fine.
|
This issue was the closest I could find to one I was going to post as new. My basic concern is to not duplicate meshes (well, all that array data). Say the imported glb/gltf file has 1 mesh. If you make a new packed scene (like those cool scripts up ^ there) then you have a 2nd mesh in the .scn file. A copy. Is there any way (in editor) to make a meshInstance3D who's mesh refers directly to the glb/gltf file? For example, I'd export a .glb with a cube and a sphere. I then want to pull the sphere into scene01 and the cube into scene02 and I don't want the meshes (etc.) to appear in either scene source file, only a resource pointing to the glb file. As things stand it feels like the glb/gltf files are sitting at the bottom of all things and taking-up memory. Am I on the wrong track? |
I am currently migrating one of my projects to Godot 4, and I need to access the mesh and materials of imported glTF files. (I have a plugin which manages the import, and more or less collects mesh instances, and then uses them for instanced rendering if specific scenes reuse base components). But the import scripts above gave me an idea how to achieve the same in Godot 4.0 with an import plugin. So I also wanted to share it here, should someone else want to do the same thing as me. @tool
extends EditorScenePostImport
func _post_import(scene):
var path := get_source_file()
print("Running post import script on file '{file}'".format({'file': path}))
var file_name := path.get_file()
path = path.substr(0, path.rfind('/'))
# Have a subfolder to store all the individual meshes and materials for each imported glTF scene
# Prefix it with _import to not clutter the directories as much
var new_subfolder := path + "/_import/" + file_name + "/"
# if the subfolder for resources already exists, clear it
recursively_delete_dir_absolute(new_subfolder)
# Now create the empty subfolder
DirAccess.make_dir_recursive_absolute(new_subfolder)
var mesh_count : int = 0
# Get valid mesh objects
for object in get_all_children_recursive(scene):
if !(object is MeshInstance3D):
continue
# Reference to the mesh
var mesh : MeshInstance3D = object
# First iterate all materials of the mesh and save them to disk
for mat in mesh.mesh.get_surface_count():
# Path where to store the extracted material
var surface_path = new_subfolder + str(mesh_count) + "_" + str(mat) + "_" + str(mesh.name) + ".res"
var material := mesh.mesh.surface_get_material(mat)
# Store the material to disk as a resource file
if ResourceSaver.save(material, surface_path, ResourceSaver.FLAG_CHANGE_PATH) == OK:
# Now using a resource loader load the same material and overwrite the old one
var new_material = ResourceLoader.load(surface_path) as Material
# This prevents the imported scene from storing the material as a sub resource
mesh.mesh.surface_set_material(mat, new_material)
print("Saved Material and overwrote resource: " + surface_path)
# Now save the mesh of our mesh object to disk
var mesh_path = new_subfolder + str(mesh_count) + "_" + str(mesh.name) + ".res"
if ResourceSaver.save(mesh.mesh, mesh_path, ResourceSaver.FLAG_CHANGE_PATH) == OK:
# Now using a resource loader load the same mesh again and overwrite our scene mesh with it
var new_mesh = ResourceLoader.load(mesh_path)
# This prevents the imported scene from storing the mesh as a sub resource
mesh.mesh = new_mesh
print("Saved Mesh and overwrote resource: " + mesh_path)
mesh_count += 1
return scene
func get_all_children_recursive(node: Node, include_self: bool = false) -> Array:
var nodes : Array = []
if include_self:
nodes.append(node)
for N in node.get_children():
if N.get_child_count() > 0:
nodes.append(N)
nodes.append_array(get_all_children_recursive(N))
else:
nodes.append(N)
return nodes
func recursively_delete_dir_absolute(folder: String) -> bool:
# Delete folder if it exists
if DirAccess.dir_exists_absolute(folder):
# Open folder
var access := DirAccess.open(folder)
# Delete all files within the folder
access.list_dir_begin()
var file_name = access.get_next()
while file_name != "":
if not access.current_is_dir():
access.remove(file_name)
else:
# If it contains more folders, first delete that folder recursively
recursively_delete_dir_absolute(folder + "/" + file_name)
file_name = access.get_next()
# Delete the now empty folder
if DirAccess.remove_absolute(folder) != OK:
return false
return true
return false Edit: By merging my code, and the Code posted above, @donn-xx should also be able to do what they wanted. |
Is this done yet? I want to import a whole car made in Blender through one .blend file and use it's meshes into an existing car scene, and be able to duplicate a tire as an instance so that they both get updated upon reimport when changed in Blender. |
Godot version
v4.0.dev.calinou [7161663]
System information
Windows 10, Ryzen 3700x, 32GB, 3060Ti, Vulkan
Issue description
The GLTF import system has changed substantially between Godot 3.4 and 4.0. Although the 4.0 system has many advantages, one of the more useful import options from the 3.4 system is currently missing.
In Godot 3.4, there is an option to import each object in a GLTF file as a separate scene, which means that you can store an entire set of related assets in a single file and import/reimport them with very little effort. In Godot 4.0, the option to set the storage type is missing, and no extra files are created when a GLTF is imported, which is quite a different experience in terms of ease-of-use compared to 3.4.
Here is the option I am talking about shown in Godot 3.4:

This is the result of this setting in the File Tree:

The file DefaultShapes.glb is imported using the above settings to automatically create many different sub-scenes. In this case, DefaultShapes contains lots of basic shapes that I can use for blocking out levels, and I'm also running them through a Post Import script to set up collision using convex hulls, boxes, spheres and capsules for each object, but without the option to store objects as individual sub-scenes, none of this works at all.
Godot 4.0 does have the option to store individual objects as Meshes, but this needs to be enabled for each object, and the file path needs to be manually set, which is a lot of extra work. Also, this way you can't add collision data automatically via script because mesh resources do not allow the user to specify collision manually and store it with the mesh, which is one of the reasons that being able to store separate scenes is so valuable.
This seems like a fairly fundamental missing feature between 3.4 and 4.0, so if possible, please add the object storage option back into the basic import settings, and additionally, add an option to set the identity transform on each object during import, as it's convenient to lay out assets in Blender so that they can be viewed and edited together, but the root transform should be reset on import unless we are importing a full scene or level. These issues are related, and there is another request for this feature here: #13980
Steps to reproduce
To compare the feature between Godot 3.4 and Godot 4.0 do the following (note that I've provided a test file attached to this bug report)
3.4
4.0
Perhaps this feature would make sense as an 'Import as:' preset, but currently it is missing.
Minimal reproduction project
DefaultShapes.zip
The text was updated successfully, but these errors were encountered: