godotengine / godot-proposals

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

Add a menu option to conert a CollisionShape2D into a CollisionPolygon2D #199

Open define-private-public opened 4 years ago

define-private-public commented 4 years ago

Describe the project you are working on: I'm trying to create a game where there is a Colosseum style area. I.e. the inside of a circle. And I need walls that keep objects inside.

Describe the problem or limitation you are having in your project: It's a real pain to try to make a (near) perfect circle manually with CollisionPolygon2D.

Describe how this feature / enhancement will help you overcome this problem or limitation: It would be much easier if I could instead create a CollisionShape2D with a Circle shape. Have Godot take the edge of the circle and turn it to a Polygon (with a user determine number of points). Then move points around as I need but retain parts that are a (near) perfect curve.

Show a mock up screenshots/video or a flow diagram explaining how your proposal will work:

  1. Create a CollisionShape2D object. Give it a shape and adjust 2a. In the Inspector, under the CollisionShape2D section, there is a new button called "Generate Polygon from Shape". An Integer field should also be supplied where I can specify how many points I want the generated polygon to have. 2b. In the Scene tree, I right click on the node. There would be an option called "Convert to Polygon". Once clicking a dialog would pop up asking me how many points for the generated polygon to have.

If this enhancement will not be used often, can it be worked around with a few lines of script?: Not really sure how to answer this. It could be very useful for 2D game developers. Though I think it could be done with GD Script.

Is there a reason why this should be core and not an add-on in the asset library?: Seems like kinda of fundament thing (to me at least).

Xrayez commented 4 years ago

Converting existing CollisionShape2D into polygons is more difficult than generating polygon(s) representing those shapes (though I think the proposal implies it). In fact the circle shape is drawn by generating a polygon with some limited number of vertices internally already, when you turn on "Visible Collision Shapes" option. Having all objects be represented as polygons could also negatively impact performance to some degree, also see continuation in https://github.com/godotengine/godot-proposals/issues/200#issuecomment-549300676.

Xrayez commented 4 years ago

For your particular use case and as a hack you can do this in 3.1/3.2: draw a donut in any sprite graphics editor, cut it slightly to connect outer and inner areas, and convert it to polygon shape (notice Sprite tool at the top of the viewport when selecting a sprite, also see some examples with instructions here):

donut-convert-dialog

That way you can get nicely decomposed collision shape:

polygon-keyholed

You can configure Simplification parameter to get a desired number of points in the circle.

This is called a keyholed representation of a polygon. Instead of defining holes, you just construct a polygon in a way that makes it look like a single polygon, see this article for instance.

polygon-convert-donut-keyholed.zip

define-private-public commented 4 years ago

@Xrayez thank you very much. That might help solve my problem right now in a fairly quick fashion. Maybe adding a "How to construction odd collision shapes" section could be added into the docs? I haven't been able to find one yet.

Also, is there a Wiki somewhere that is a sort of cookbook of recipes for Godot?

Xrayez commented 4 years ago

Unfortunately I feel like this topic is a bit niche so it's difficult to find learning resources on this. The features are quite new as well. I'm experimenting with stuff myself so I can't really recommend some specific resources, but googling helps. Books are also valuable if you want to get more in-depth understanding. You can always request tutorials to be written in the docs.

Xrayez commented 2 years ago

I'm trying to create a game where there is a Colosseum style area. I.e. the inside of a circle. And I need walls that keep objects inside.

@define-private-public if you're still interested, it's quite easy to do this in Goost by using PolyCollisionShape2D and PolyCircle2D nodes now (no code required):

image

See example project at https://github.com/goostengine/goost-examples/tree/gd3/2d/colosseum