Godot-proposals: Add support for hullcasting

Created on 15 Sep 2019  路  10Comments  路  Source: godotengine/godot-proposals

Describe the project you are working on:

I'm working on a simple C# game that makes use of RayCast2D a lot.

Describe how this feature / enhancement will help your project:

Currently i'm simply using a hacky solution of using multiple raycasts to simulate a hullcast.

I can see a hullcast feature being very useful in other ways. If you can assign the hull any shape, you could do sphere hullcasts, capsule hullcasts, etc.

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

Not really needed. Similar to how RayCast and RayCast2D exist, there would be HullCast and HullCast2D nodes.

Describe implementation detail for your proposal (in code), if possible:

A hullcast object really only needs to know how far to cast, and what shape to cast from start point to end point. Maybe have a nice preview in the editor to make it easier to visualize how the hullcast will work.

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

In general i think this sort of thing should be part of the core feature set. It has applications in many different game settings.

physics

Most helpful comment

I've managed to implement node-based shape casting in 2D.

Editor view

godot-shape-cast-2d

Inspector

godot-shape-cast-2d-inspector

API

godot-shape-cast-2d-api

Description / Proposed implementation

The implementation is based on RayCast2D (copy-pasted and adapted), uses the mentioned cast_motion along with get_rest_info internally, so in most cases it reflects RayCast2D API, with the following differences:

  • obviously you need to assign any Shape2D resource before using. For 2D, CircleShape2D is instantiated by default.
  • ability to configure collision margin for shapes.
  • casting can work with cast_to == Vector2(). In this case, such node can be used as a general-purpose, (continuous) collision detection area which can overcome limitations of Area2D.
  • can return multiple results (the number of results is limited by max_results property for performance reasons). get_closest_* methods should be used instead if you come from RayCast2D.
  • exposed collision_result as a property so that if there's a need to fetch more collision information not provided by the API by default (collider's linear_velocity, metadata etc).
  • get_closest_collision_safe/unsafe_distance used for querying the intersections exactly outside/inside collision. You can move the shapecast along safe distance to repeat the process from that point without the node being stuck inside the collider, for instance.

Contributing considerations

  • I've managed to implement this via C++ modules in my own project, and replaced some GDScript classes already with it. If you think it's worth adding a whole ShapeCast(2D) to Godot core and you feel like the described implementation is logical/fits the requirements, I can make a PR.
  • I cannot use 4.0 for now, so I'd much rather keep using 3.2, some 4.0 refactorings has already introduced inability for such classes to be cross-compatible, so before making a PR I'd like for the engine to become more or less stable so I can git checkout master again.
  • I don't use 3D features at all, so I don't feel confident to port this to 3D and being able to test it properly, but according to RayCast class this shouldn't be too hard I guess. If someone else is willing to port this, it would be great, I can make a PR. 馃檪

All 10 comments

Please check if https://docs.godotengine.org/en/3.1/classes/class_physicsdirectspacestate.html#class-physicsdirectspacestate-method-cast-motion this does what you want?

Edited:

2d version https://docs.godotengine.org/en/3.1/classes/class_physics2ddirectspacestate.html#class-physics2ddirectspacestate-method-cast-motion

This might not be related but it reminds me of something similar to what I'm currently doing with multiple Area2Ds:

areas_nested

For instance, the character can react accordingly depending on where the object is located within these areas.

Good trick, I used to use an Area2D, and then was disappointed with how it was impossible to tell the relative position where the contact occurred, and went back to using a ton of raycasting.

@fire: how exactly is that used? Can I assign any shape or does it need to be the shape of the body's collider, for instance?

Please check if https://docs.godotengine.org/en/3.1/classes/class_physicsdirectspacestate.html#class-physicsdirectspacestate-method-cast-motion this does what you want?

Edited:

2d version https://docs.godotengine.org/en/3.1/classes/class_physics2ddirectspacestate.html#class-physics2ddirectspacestate-method-cast-motion

Nice to know those exist. I suppose my request would be that this is adapted to function similarly to a RayCast node.

So to clarify, what would you expect from a hullcasting? Also could the proposal be renamed to shape casting perhaps? That's where I misunderstood the initial proposal.

Unity seems to have dedicated individual classes for elementary shapes like Physics.SphereCast, see also https://github.com/godotengine/godot/issues/2217#issuecomment-587078968.

IIRC hullcasting and shape casting are the same.
And yes, for 99% of uses I can imagine dedicated classes for shapes such as sphere/circle, rect is the way to go.

I've managed to implement node-based shape casting in 2D.

Editor view

godot-shape-cast-2d

Inspector

godot-shape-cast-2d-inspector

API

godot-shape-cast-2d-api

Description / Proposed implementation

The implementation is based on RayCast2D (copy-pasted and adapted), uses the mentioned cast_motion along with get_rest_info internally, so in most cases it reflects RayCast2D API, with the following differences:

  • obviously you need to assign any Shape2D resource before using. For 2D, CircleShape2D is instantiated by default.
  • ability to configure collision margin for shapes.
  • casting can work with cast_to == Vector2(). In this case, such node can be used as a general-purpose, (continuous) collision detection area which can overcome limitations of Area2D.
  • can return multiple results (the number of results is limited by max_results property for performance reasons). get_closest_* methods should be used instead if you come from RayCast2D.
  • exposed collision_result as a property so that if there's a need to fetch more collision information not provided by the API by default (collider's linear_velocity, metadata etc).
  • get_closest_collision_safe/unsafe_distance used for querying the intersections exactly outside/inside collision. You can move the shapecast along safe distance to repeat the process from that point without the node being stuck inside the collider, for instance.

Contributing considerations

  • I've managed to implement this via C++ modules in my own project, and replaced some GDScript classes already with it. If you think it's worth adding a whole ShapeCast(2D) to Godot core and you feel like the described implementation is logical/fits the requirements, I can make a PR.
  • I cannot use 4.0 for now, so I'd much rather keep using 3.2, some 4.0 refactorings has already introduced inability for such classes to be cross-compatible, so before making a PR I'd like for the engine to become more or less stable so I can git checkout master again.
  • I don't use 3D features at all, so I don't feel confident to port this to 3D and being able to test it properly, but according to RayCast class this shouldn't be too hard I guess. If someone else is willing to port this, it would be great, I can make a PR. 馃檪

I have created my own proposal regarding this, because I have some specific implementation details which might be worth discussing separately: #710.

I would recommend just renaming the raycast nodes to shapecast and then allowing them to take a shape or ray (ray possibly being a shape type?)

if this gets added it would make rays able to be drawn.

(ray possibly being a shape type?)

Note that RayShape and RayCast are different, the former is used as separation shape rather, created proposal for renaming: #711.

if this gets added it would make rays able to be drawn.

See my response there https://github.com/godotengine/godot/issues/6750#issuecomment-613747243.

Was this page helpful?
0 / 5 - 0 ratings