Crash when using raycast to see if hit Game Object

I’m trying to do what I’d do in other engines, doing a raycast across my 2D plane (z = 0) to see if I hit any Game Objects on that plane. But when I do the raycast dmengine is crashing, so I guess I am doing something wrong. I get this error message:

Assertion failed: (r.LengthSquared() > 0.0f), function RayCast, file …/src/box2d/Box2D/Collision/b2DynamicTree.h, line 232.

My code is very simple, just doing this:

function init(self)
    msg.post(".", "acquire_input_focus")
    self.raycast_collision_groups = { hash("group1") }
end

function on_message(self, message_id, message, sender)
  
    if message_id == hash("ray_cast_response") then
        -- act on the hit
    end
end

function on_input(self, action_id, action)
   
    if action_id == hash("touch") and action.pressed then
    	physics.ray_cast(vmath.vector3(action.x, action.y, 10), vmath.vector3(action.x, action.y, -10), self.raycast_collision_groups)
    end
end

Does anyone have any idea what is wrong here? I thought a raycast for z = 10 to z = -10 would cross the plane and the message would let me know if any Game Objects were hit.

I do have one Game Object in the scene with a collision component in group “group1”.

If you have 2D physics I think the z-component of the vector is ignored when raycasting, resulting in a zero length raycast, which causes the engine to crash

Yep, changing the physics to 2D does stop the crashing. Thanks!

Unfortunately I don’t seem to be getting a ray_cast_response when I am clearly clicking on a Game Object …

Is there any specific mask you need to add to the collision object to allow it to detect collisions with raycasts? I can’t for the life of me see why it isn’t detecting the collision.

That is because action.x and action.y is in screen space and the raycast is in world space. In order to determine if a game object is clicked or not, here is one of may threads discussing the topic:

Yeah, I read that but I mistook the response action.x and action.y to be world space as the action object already included screen space values that were the same. I guess I was wrong there!

{
  x = 459.5,
  pressed = true,
  y = 187.5,
  screen_y = 188,
  screen_dy = 0,
  screen_dx = 0,
  screen_x = 459,
  dx = 0,
  value = 1,
  repeated = true,
  released = false,
  dy = 0,
}

To be honest, I am not convinced this is a world space issue. I have just started the project and have not done anything funky with any cameras.

If I log the world position (using go.get_world_position()) and then click approximately in the middle of the object I get very similar values:

DEBUG:SCRIPT: vmath.vector3(200, 200, 0)
DEBUG:SCRIPT: (action.x, action.y) = (200.5, 197.5)

I can’t help but feel that my raycast is’t colliding correctly, more likely due to settings.

That might of course be the issue as well. Do you have group1 set on a collision object on that game object, and does that collision object contain a shape?

Yes, they were both set.

I the meantime I’ve done an ugly solution based on the thread that you linked, where I just compare the touch x,y with the x,y of the objects (with a little either side). It works but feels a bit hacky.

In 2D the ray needs to travel across the plane and start outside of the shape for it to be regarded as a hit. Sending the ray from within the shape and then crossing outside of it would not be a hit. For your particular case, I would recommend you temporarily spawn a “touch” game object whenever you touch the screen and let that collide with whatever you are touching. I think this would be the simplest approach, and you also get a nice radius of the touch-object to reflect the width of your finger if you see what I mean.

If you just have a few interactive things with a simple sphere-like shape you would like to interact with, implementing it yourself in Lua seems perfectly reasonable to me as well. If their shapes are more complex, or there are many of them, the physics approach would be better.

An improvement we are going to make is to send response messages even when the rays miss, for both debugging and simpler logic. Can’t give you an ETA though, sorry about that.

2 Likes

That’s a clever idea about the touch object, I hadn’t considered that. It may well be a better solution as then I would have to end up using screen space values. I think I’ll give that a go tomorrow.

Thanks!