Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a batch RayCast method to cast all the way up to a specific object, caching all collisions #25695

Closed
willnationsdev opened this issue Feb 8, 2019 · 11 comments

Comments

@willnationsdev
Copy link
Contributor

willnationsdev commented Feb 8, 2019

Issue description:
I often hear about situations where people want to raycast from point A to B until they possibly hit Object X, and then they want to know what all besides X they hit along the way. This is essentially a batched set of RayCasts that adds exceptions as it goes along each time hits the target X, collects all the records into an array, undoes all of the exceptions, and then returns the data. Only, it's a waste to have to make so many different calls to set_cast_to and force_update_raycast, especially cause it has to travel up to the previously hit obstacle every single time, re-doing a bunch of work.

One example use case I can think of, which comes up frequently, is people wanting to see their character behind objects, but they need to know what all objects to make transparent in order to make that happen.

Steps to produce:
I may be out of my element here, so I'm not sure if the PhysicsDirectSpaceState already has this (or maybe I didn't understand its intersect_ray method properly), but here's my suggestion: we create a new method in PhysicsDirectSpaceState, intersect_ray_until that has all the same parameters, but also adds an RID where it keeps running all the way up to the cast_to point and builds a vector of RayResults as it runs rather than stopping at each collision along the way. This could then culminate in an identically named method in the scripting API where one gives a cast_to point and a target object (could be a body, could be an area) and the RayCast could then provide access to an array of structs (similar to the changes we made with KinematicBody's move_and_slide letting users get the collision count and individual collision records).

Thoughts?

@willnationsdev willnationsdev changed the title Add a batch RayCast method to cast all the way up to a specific object, returning all collisions Add a batch RayCast method to cast all the way up to a specific object, caching all collisions Feb 8, 2019
@Zylann
Copy link
Contributor

Zylann commented Feb 8, 2019

For the visibility use case you are describing, I would suggest using intersect_shape with a LineShape (catching all hits along it, not just the first), but that shape doesn't exist... So the only workaround would be to use a thin BoxShape with proper orientation.

@willnationsdev
Copy link
Contributor Author

@Zylann If that's the case, then it seems like the proper "answer" is then to just modify the API documentation to reference that as an option, since it is definitely not readily apparent to most users (like myself and the many similar posts I see on forums). I'll try to add some later.

@eon-s
Copy link
Contributor

eon-s commented Feb 8, 2019

No line, but SegmentShape to name it correctly (and like the corresponding Shape2D), by definition rays should stop on first hit.

@willnationsdev
Copy link
Contributor Author

@eon-s Are you suggesting then that a "find collisions from A to B up until Object X" method should be a feature, but it shouldn't be in the RayCast class, or that a method like this should never exist and users should hand-code all of the logic themselves in scripts?

@Zylann
Copy link
Contributor

Zylann commented Feb 8, 2019

I think SegmentShape2D exists but SegmentShape is missing for 3D (Line is mathematically incorrect because it's infinite).

@eon-s
Copy link
Contributor

eon-s commented Feb 8, 2019

@willnationsdev no, I was making a small correction to what Zylann said, and is detailed in his other answer.

Of course, workarounds exists and one can be to cast a ray adding exceptions on hit until you get no hits (a simple while loop) but a Segment shape can have many other uses.

@willnationsdev
Copy link
Contributor Author

@eon-s ah, I gotcha. Yeah, it'd be nice to have a SegmentShape for 3D.

@henriiquecampos
Copy link
Contributor

Isn't this possible with a simple Area and RayShape? Areas cache everything they are colliding with using Area.get_overlapping_* which can be bodies or other areas.

@eon-s
Copy link
Contributor

eon-s commented Aug 23, 2019

@henriiquecampos I agree that Area may be better suited for this if we want to keep rays lightweight as they are.

@Xrayez
Copy link
Contributor

Xrayez commented Feb 17, 2020

Related to #14608.

@madmiraal
Copy link
Contributor

Feature and improvement proposals for the Godot Engine are now being discussed and reviewed in a dedicated Godot Improvement Proposals (GIP) (godotengine/godot-proposals) issue tracker. The GIP tracker has a detailed issue template designed so that proposals include all the relevant information to start a productive discussion and help the community assess the validity of the proposal for the engine.

The main (godotengine/godot) tracker is now solely dedicated to bug reports and Pull Requests, enabling contributors to have a better focus on bug fixing work. Therefore, we are now closing all older feature proposals on the main issue tracker.

If you are interested in this feature proposal, please open a new proposal on the GIP tracker following the given issue template (after checking that it doesn't exist already). Be sure to reference this closed issue if it includes any relevant discussion (which you are also encouraged to summarize in the new proposal). Thanks in advance!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants