godotengine / godot-proposals

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

Add a destruction system #7782

Open ywmaa opened 1 year ago

ywmaa commented 1 year ago

Describe the project you are working on

I know a similar issue exists, but I can't find it useful for describing the feature : https://github.com/godotengine/godot-proposals/issues/2082

a 3D Hero Shooter.

Describe the problem or limitation you are having in your project

no Destruction system.

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

Add DestructibleBody3D which Inherits RigidBody3D, and handles destruction system.

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

The Setup

so the DestructibleBody3D will inherit RigidBody3D, it will have a specific function :

func damage(impact_point:Vector3=Vector3.ZERO, impact_force:float=1.0, impact_radius: float=1.0)

also it will have a specific physics material containing the physical specs of the object like (material_bonds_strength, etc) and we will provide Default values for specific materials like (Wood, Glass, Metal).

also the node will show a warning in the editor that it requires a MeshInstance3D as a child (Needed for mesh slicing), and you will need to provide a material for the innner side of the MeshInstance3D that is going to be visible after the destruction happens.

How does work internally

Two Option That I want to add by default (Precomputed Destruction, Procedural Destruction). Both are opt-in features, I will explain how should each one work, and the merits of each one :

Precomputed Destruction

the editor will allow for generating precomputed Destruction Objects, so you will have a Voronoi Texture, and you set its values, the editor shows to you how it will cut the mesh.

then you press Compute Button somewhere (it could also be a built-in function so the developer can compute procedural assets)

Now the DestructibleBody3D will slice the mesh, and create the sliced MeshInstances3D + Collisions for each and adds a parent to them (RigidBody3D or DestructibleBody3D to them if developer chooses, but it will increase the cost of the original DestructibleBody3D), now we can either cache them or add them to the scene and hide them.

finally in game when something registers damage(), based on the provided values (material_specs + impact_force + impact_point + impact_radius) it will start adding normal force to either the RigidBody3D or DestructibleBody3D Childs (but in case of DestructibleBody3D it will add extra damage, after subtracting the force already taken by the parent DestructibleBody3D).

so now you should see your object exploding or something if you add enough force, else the object will break the specific part was damaged by the impact (I have an algorithm in mind, but I would like to first hear opinions on this approach).

Pros :

Better Performance compared to Procedural Destruction

Cons :

Not Totally acurate since it will be limited the Precomputed stage of it, it won't break anymore. OR, we can add an option to combine both, and make the first destruction use the precomputed then use Procedural Destruction.

Procedural Destruction

it will just do the same as Precomputed Destruction, but instead no Compute, the developer will provide GrayScale Texture that takes the shape of the destruction, and when something registers damage, it will do the slicing + creating collision shapes on the Fly

Pros :

Procedural so it will mimic a destruction more "Realistically". for example based on the provided texture we can just keep breaking the same object.

Imagine you add a texture that got the image of glass breaking : image

it will use this image for the impact_position, so each type you hit Position X, it will slice the mesh from there in the shape of the provided texture, making the glass look like it is shattering

Cons :

Very Performance heavy as it does Realtime Mesh Generation + Collision Generation

Extra Features (Edit 0)

Recording Destruction Positions (For Reversing the Destruction) Opt-in feature

Multiplayer Sync (can be bandwidth heavy) Opt-in feature

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

Yes it is not required to be part of the engine ,but actually any 3D game can find this useful, though I don't insist on this feature being part of Godot Directly, I will anyway do it for my game, I just here to see if the Godot Community wants this feature by default, and to discuss how to implement in such case, since from my search this feature is implemented in certain number of publicily available engines.

I will work on the feature sometime near for my game in Godot, I am just checking if it is accepted to do it as part of the engine instead of GD Extension

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

No reason, but to have extra features in Godot.

(Edit 0), can be useful for most 3D games, stylized or not, it is a physics feature for the engine, like SoftBody3D or SkeletonIK. and having it in core will make it maintained for every version onward until the engine developers decide to make it deprecated.

AThousandShips commented 1 year ago

No reason, but to have extra features in Godot.

This is not exactly what this question asks for, the question is why it is necessary to put in core, as opposed to as a plugin or add-on.

Adding a feature to core requires that it is something enough people will use to justify the work to create, maintain, and update it. This means that it either has to be very easy to do so, or that it is a sufficiently popular or needed feature.

This sounds like something that is very game specific and not something that's easy to do generically enough to cover all normal use cases, different styles, different requirements, different performance needs, etc.

ywmaa commented 1 year ago

This is not exactly what this question asks for, the question is why it is necessary to put in core, as opposed to as a plugin or add-on.

Yes it can be an addon anyway, but for better maintenance it can be core, after all it is part of the Physics Engine, and it is like having VehicleBody3D or something, not all games need VehicleBody3D, but some may find it useful, and some find it crucial.

I am doing this proposal to only see if the Godot Community Really Needs this feature or no.

ywmaa commented 1 year ago

This is not exactly what this question asks for

added extra reason in the OP.

AThousandShips commented 1 year ago

I would argue that a majority of games made with Godot would not need this feature, and unlike VehicleBody3D this isn't a trivial detail, VehicleBody3D is relatively minimal code wise (just 890 loc) so it isn't really a good comparison to an entire new detail in physics with a lot of complexity to it

Further, and this is a pretty important point: It is very unlikely to be so general that it serves every possible users needs, or even the vast majority, without being extremely dynamic and complex code wise, how to handle how things break etc.

This means that it is far better to have plugins and add-ons, which each serve different styles or purposes, in smaller scope

For example, a destruction system can mean any of the following:

These are very different sitautions

RedMser commented 1 year ago

I am just checking if it is accepted to do it as part of the engine instead of GD Extension

Note that you can also create a module. This makes it compile as part of the engine (more seamless dev experience than gdextension), but can easily be added and removed as a separate git repository without maintaining your own branch/fork of the entire engine.

Zireael07 commented 1 year ago

@ywmaa Note that VehicleBody3d isn't a good example because it's on the chopping block to be moved out of core into an official module

ywmaa commented 1 year ago

Note that VehicleBody3d isn't a good example because it's on the chopping block to be moved out of core into an official module

Lol then my point just breaked down.

Though I edited the OP, and I compared it to SoftBody3D or SkeletonIK.

Edit : typo