godotengine / godot-proposals

Godot Improvement Proposals (GIPs)
MIT License
1.16k stars 97 forks source link

Allow specifying custom mesh resources as collision data in the Advanced Import Settings dialog #8681

Open tomankirilov opened 11 months ago

tomankirilov commented 11 months ago

Describe the project you are working on

Multiple 3D games.

Describe the problem or limitation you are having in your project

I am working on many and different games professionally. I've been pushing for moving to Godot at my studio but sadly we only made prototypes because of limitations. A big one is the pipeline for importing 3D objects.

  1. Importing meshes adds a Node3D root (or other node)
  2. The top level in a static object is a mesh, followed by the type (StaticBody3D). For a dynamic/kinematic body the top node is the body itself RigidBody3D/KinematicBody3D.
    • This inconsistency leads to confusion.
    • Often you need to have access to both the body type and the mesh/collider. In case of importing both a mesh and collider and you want it to be a specific type you need to create an inherited scene and edit it.
  3. Importing meshes does not allow you to choose a custom collider. You have the following options available. They work often, but in many cases a custom and specific collider is required.
    • Decompose convex
    • Simple convex
    • Trimesh
    • Default shapes

Describe the feature / enhancement and how it helps to overcome the problem or limitation

This problem can be solved in multiple ways. I have ideas, but ultimately I want to raise the problem for discussion. Possible solution 1:

Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams

In the "Unreal way" there will be a new node that works as a combination of "MeshInstance3D", "PhysicsObject3D" and "CollisionShape3D". In the other idea there will be an option in the Advanced Import Settings to import a node as a specific type. If the node is a CollisionShape3D it will automatically convert the mesh to Convex or ConcavePolygonShape3D.

If this enhancement will not be used often, can it be worked around with a few lines of script?

I believe this enhancement will make the workflow better and will be much more suited for most cases. In case of my second proposal - it can be worked around with an import script, but it will only fix a part of the problems and will be quite hacky.

Is there a reason why this should be core and not an add-on in the asset library?

It affects core functionality.

Calinou commented 11 months ago
  1. Importing meshes adds a Node3D root (or other node)

This is being tracked in https://github.com/godotengine/godot-proposals/issues/7494.

  1. The top level in a static object is a mesh, followed by the type (StaticBody3D). For a dynamic/kinematic body the top node is the body itself RigidBody3D/KinematicBody3D.

I'm surprised it was implemented this way, considering the order doesn't matter for a StaticBody3D (as long as the collision shape is a direct child of the StaticBody3D).

Merge visual meshes with physics objects.

This is a compatibility-breaking change that would enforce a 1:1 mapping between meshes and collision bodies, which I don't think is a good idea. It's quite common to have a single physics body composed of multiple MeshInstance3D nodes, or a single mesh featuring multiple collision shapes.

  1. Importing meshes does not allow you to choose a custom collider. You have the following options available. They work often, but in many cases a custom and specific collider is required.

If you have a simplified collision mesh in the same 3D scene source file, you can give it a -colonly suffix in the 3D modeling software.

tomankirilov commented 11 months ago

A small update. If a mesh is exported with the -colonly suffix and imported in Godot it will act as a collider only as @Calinou mentioned. In combination with this script below you can automatically export all meshes and colliders as resources and use them in your custom scenes:

@tool
extends EditorScenePostImport

func _post_import(scene):
    iterate(scene)

func iterate(node):
    for child in node.get_children():
        var file_path = get_source_file().get_base_dir() + "/"

        if child is MeshInstance3D and child.mesh:
            var file_name = file_path + child.name + ".mesh"
            ResourceSaver.save(child.mesh, file_name)
            print("Exporting Mesh: " + child.name + " to " + file_name)

        elif child is CollisionShape3D and child.shape:
            var file_name = file_path + child.get_parent().name + ".shape"
            ResourceSaver.save(child.shape, file_name)
            print("Exporting Collider: " + child.name + " to " + file_name)

        iterate(child)

This is not solving all the issues but allows a clean workflow.

xzbobzx commented 11 months ago

I'd like to bring up that I'm really not a big fan of the "add suffixes in your 3D model to control importing functionality in the engine", to me that still really feels like splitting up one task among two different programs, and gets really annoying when you're dealing with third party 3D models that were not originally meant to be used with Godot.

It would be a lot lot lot nicer if all of the suffix functionality gets added to the import-side, with checkboxes or another UI solution.