How to check if a RayCast2D is colliding to the left or to the right of the center of the CollisionShape2D?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By spazzybear

If the CollisionShape2D is a circle and my player is moving towards it while projecting a RayCast2D, how do I check if the RayCast2D is left or right of the center of that circle? Thanks!

:bust_in_silhouette: Reply From: DaddyMonster
  1. Take the collision object’s normal which you can get from the raycast obj (get_collision_normal() method).
  2. get the raycast vector and normalise it.
  3. Rotate the raycast vector by PI/2 (90 degrees)
  4. Finally take the dot product of the two vectors. Whether the dot product is negative or positive will tell you which way it’s pointing.

Good luck!

nb: This only works when the ray cast collides. If you want it to know which side it was on regardless of whether it collided then let me know, you’ll need a different approach.

Thank you for responding. I have a few noob follow-ups, please:

  1. Check. I get two values
  2. How do I get the raycast vector and normalize it?
  3. Got it.
  4. Could you explain this further?

Thanks!

spazzybear | 2021-11-14 21:20

No worries! Here, I’ll try to demystify the maths too for you:

  1. Like this: RayCast2d.cast_to.normalized()

Normalising gives a new vector in the same direction a length/magnitude of 1 known as a unit vector.

So Vector2(0, 14).normalized() normalised is Vector2(0, 1). You calculate this by working out the length and then dividing the vector by it. Working out the length is pythagoras: so Vector2(0, 14)/sqrt(x*x, y*y)So, Vector2(0/14, 14/14) in this example.

  1. There are two ways to multiply vectors; dot and cross products. The dot product is the simplest. You put in two vectors and you get a number out. In code it’s looks like this: Vector2(1, 0).dot(Vector2(1, 0))the result is a scalar (a number) - in this case 1.

In maths it’s first_vec.x * second_vec.x + first_vec.y * second_vec.y

When dealing with normalised vectors (99.9% of the time you will be), the dot product is a measure of how similar they are. So, a dot product of 1 means that they are pointing in the exact same direction. A dot of -1 means that they are pointing in opposite directions. Zero is perpendicular/orthogonal (but it doesn’t tell you which way, if the dot is zero and you rotate 180, you still have zero).

This why there’s step 3, by rotating 90 degrees. If you didn’t do that you’d know they were misaligned because the result would be less than 1 but you wouldn’t know wich way. However, if the raycast is at exactly 90 degrees to the RayCast then the output is zero. Like this:

Vector2(1, 0).dot(Vector2(0, 1)) is:

1 * 0 = 0
0 * 1 = 0
0 + 0 = 0

But once the normal and the raycast aren’t precisely aligned (like they will if you hit a circle to the left or right) then the rays will be misaligned orthogonally and you’ll get a positive / negative value depending on whether it’s to the left or right.

Wow, I wrote a lot!

DaddyMonster | 2021-11-14 22:29

Thank you very much! It was so kind of you to explain the math in detail, I appreciate it!

spazzybear | 2021-11-16 19:56

You’re welcome! Just I know I wish I knew that when I was starting off so I told you.

Let me know if you get it going. Good luck!

DaddyMonster | 2021-11-17 23:05