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

RayCast2D behaves erratically if a lot of exceptions are added #37736

Closed
Tracked by #39876
whitelion351 opened this issue Apr 10, 2020 · 8 comments
Closed
Tracked by #39876

RayCast2D behaves erratically if a lot of exceptions are added #37736

whitelion351 opened this issue Apr 10, 2020 · 8 comments

Comments

@whitelion351
Copy link

Godot version:
3.2.1.stable

OS/device including version:
Windows 10 64-bit

Issue description:
I have an instanced object moving to the right with 2 raycasts attached as children. One pointing left and one pointing down. They are both enabled and set to detect Areas. As it moves right, it places a "tail_segment" (think of the game snake) in its previous location with an Area2D attached. There are other instances of this object that are spawned in front of the primary object and move upwards. They have the same action of placing "tail segments" behind them as they move. After about 15-20 seconds, the raycast that is pointing left on the primary object will start missing the segments i am placing. The first object hit by the raycast that is a tail of the primary should turn green. It slowly gets worse the longer the project is run.

Steps to reproduce:
Run the project and watch the raycast detect objects to the left of the primary object. The problem does not occur if no objects are spawned over time by setting can_spawn = false in Environment.gd. Pressing Enter can toggle spawning while project is running

Minimal reproduction project:
raycast_issue.zip

@bojidar-bg
Copy link
Contributor

bojidar-bg commented Apr 10, 2020

I ran the attached project, but I'm not sure what I should be looking at in it. It looks the same to me, no matter how long I run it (Arch Linux, 3.2.1 stable):

image

@whitelion351
Copy link
Author

whitelion351 commented Apr 10, 2020

Hi, thanks for looking. The green block on the red line should stay a constant distance from the right most side which is where the raycasts are coming from. When I run the project, the raycast will not detect any new blocks that are placed for a random amount of time. I have included a gif that hopefully can explain it better than I can.

raycast_issue_win10

You did give an idea though. I will run it on my Ubuntu machine and report back

@whitelion351
Copy link
Author

I ran the project on my Linux machine and while the problem is still there, it does not seem nearly as bad. I think i have discovered though, that is has something to do with adding exceptions to the raycast in gdscript. If the raycast hits an object that was not created by its parent, (In this project case, if it hits a blue block instead of a red one) it will add an exception and do a force_raycast_update. I have confirmed that it is not adding any red blocks to the exceptions list.
However, if I remove the code for adding exceptions then it works as expected, albeit it starts detecting the blue blocks as well.

@whitelion351
Copy link
Author

whitelion351 commented Apr 11, 2020

It is definitely raycast exceptions. I have made a much simpler project demonstrating the issue I am having. Behold:
raycast_exceptions_issue.zip

raycast_exceptions_issue_win10

The top line is being drawn and added to the bottom line's raycast exceptions. The bottom line does the same as it did before; raycasts to the left, the block it hits changes color to green and then it moves to the right. The green block should always appear to be 2 blocks away from the right most block.
But this does not happen. The raycast starts missing blocks as if they are in it's exceptions.
The problem also goes away if I don't add the top line of blocks to the scene tree

@whitelion351
Copy link
Author

I found that if i clear the raycast exceptions and do a force_raycast_update at the beginning of _physics_process, then i get the expected behaviour. Is there a limit or some quantity of exceptions that would cause a raycast to behave as depicted above? I will wait to hear from someone before I close this issue in case it actually is an issue that needs correcting.
BTW I love godot. Keep up the good work guys!

@whitelion351 whitelion351 changed the title RayCast2D misses a lot of collisions in this scenario RayCast2D behaves erratically if a lot of exceptions are added Apr 12, 2020
@madmiraal
Copy link
Contributor

The problem is the StaticBody2Ds that are added to the RayCast2D exceptions are being freed, but not removed from the RayCast2D exceptions. The memory of the freed StaticBody2D is being reallocated to new StaticBody2Ds, which are considered to already be members of the RayCast2D exceptions. This is why clearing the RayCast2D exceptions at the beginning of _physics_process solves the problem. Alternatively, they can be removed from the RayCast2D exceptions before being freed.

@madmiraal
Copy link
Contributor

Closing as fixed on master with 4f16397. This ensures that RIDs are compared using their ID not the pointer to the underlying data, which can be reallocated when freed.

@madmiraal madmiraal added this to the 4.0 milestone Dec 1, 2020
@whitelion351
Copy link
Author

That is a very good explanation. Thankyou for looking into it.

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

4 participants