godotengine / godot-proposals

Godot Improvement Proposals (GIPs)
MIT License
1.12k stars 69 forks source link

Add MultiColliderInstance #4344

Closed mrjustaguy closed 2 years ago

mrjustaguy commented 2 years ago

Describe the project you are working on

3D Game Forests

Describe the problem or limitation you are having in your project

MultiMeshInstance is great for placing a bunch of identical meshes semi randomly across a given mesh, but there is no way to couple that with collision shapes for said meshes.

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

creating a MultiColliderInstance (and allowing it to be generated from MultiMeshInstance, or well with the same positioning and scaling data) would allow for quick and easy creation of scattered objects across specified surfaces

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

Same logic as MultiMeshInstance, just for Static Bodies instead of meshes, and instead of mesh that you're scattering on, have it look for MultiMeshInstance and use it's settings.

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

No.

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

MultiMeshInstance is core, this would just add a collision counterpart for instances where they are useful and need to be tied to MMI.

Calinou commented 2 years ago

You can create a trimesh collision shape that matches the positions of all meshes. Depending on the amount of instances that need collision, it may or may not be faster than using lots of primitive collision shapes.

Diddykonga commented 2 years ago

I can understand the thought behind the idea, but In practice I believe this would only produce negative results.

If you had a forest of trees, using this MultiColliderInstance, if there were only a single tree next to an important object, such as the Player, during Broad-Phase the entire Forest would be included in the BVH leaf to check against the Player, even if only a single tree were next to them, thereby producing negative results and lowering performance.

I may be missing something, but I dont think this would be beneficial.

mrjustaguy commented 2 years ago

I think I've expressed myself wrong.. idea is more to create a way to use MultiMeshInstance data, to just scatter static bodies for a given MMI.

This could maybe be done with a GDScript tool, but the issue is the MMI data isn't documented enough to make it. also having a single node that batches all the static bodies does have advantages (and yes the SBs are treated much like individuals still, not as one mega static body) like the fact that you don't have to deal with thousands of individual nodes, something that tends to crash the editor quite a bit and this would possibly help. See https://github.com/godotengine/godot/issues/59095

TLDR 1) Need to scatter Static Bodies for MMI Collisions (a difficult task for GDScript given the lack of documentation) 2) Tons of nodes suffer from issues that a single node batching shouldn't suffer from

Calinou commented 2 years ago

(a difficult task for GDScript given the lack of documentation)

In this case, we should improve the documentation :slightly_smiling_face:

Diddykonga commented 2 years ago

I think I understand better, while this technically can be done with the lower level Physics Servers, having a partner node that gives quick access to static collisions for MMI data, could definitely be useful as a higher level node, although I'm not sure if having as a separate node would make anysense considering it would literally only be useful when paired with an MMI, and anytime the MMI changes so would the MCI.

Maybe a collision checkbox on the MMI Node itself, that would setup the collision for its MMI data through the Physics Servers?

mrjustaguy commented 2 years ago

Integration of this into MMI itself would work too, and would actually make more sense

mrjustaguy commented 2 years ago

Closing as Workaround was figured out by using Multi Mesh Instance Data, and isn't actually that difficult and performs just fine, just the Documentation of the Data is poor so a bit of trial and error determining what is what.

MountainLabsYT commented 2 months ago

You can create a trimesh collision shape that matches the positions of all meshes. Depending on the amount of instances that need collision, it may or may not be faster than using lots of primitive collision shapes.

Right, but can you do that in gdscript?

Zireael07 commented 2 months ago

Yes you can, and easier than when they proposed it, as make trimesh collision was exposed to scripting

MountainLabsYT commented 2 months ago

Yes you can, and easier than when they proposed it, as make trimesh collision was exposed to scripting

How? I currently need this.

Calinou commented 2 months ago

MeshInstance3D has a create_trimesh() collision node, but MultiMeshInstance3D doesn't. The Mesh resource also has a create_trimesh_shape() method. What you could do is:

Note that this does not take individual instance scaling into account. For this to work, you'd need to create a temporary MeshInstance3D, position/scale it according to the MultiMesh instance data, then call create_trimesh_collision() on it, move the CollisionShape3D node outside (while setting its position) and remove the MeshInstance3D.