[SOLVED] How to use Raycast?

I’m trying to do a raycast from a cube. I’m using the function raycastFirst() so my line of code is:

var result = this.app.systems.rigidbody.raycastFirst(this.entity.getPosition(), pc.Vec3.DOWN);

It’s supposed to return a plane that it’s directly under the cube (actually it’s surrounded by planes in every direction for testing so it should hit any of them) but it always returns null. I already applied the rigidbody component to the planes.

Hi @Visama,

Apart from a rigid body component you need to also add a collision component to your entities, and configure its size.

If you still experience problems try posting a sample project here to take a look.

1 Like

I forgot that. I’ve just applied the collision component and configured their sizes too, but It still returns null. I only find tutorials that talks about doing raycasts from the mouse position and none from an entity, maybe my problem is that I’m using wrong raycast, and it only works with screen or sth.

Raycasting can be tricky to implement initially since it isn’t straightforward to debug.

Try posting a sample project that replicates your project to take a look if you like.

I was trying to make a sample project to send you, and I noticed it works in that project with the same things I did on the first one. So dunno what’s wrong. Raycasting is working actually, and it should work in the other.
https://playcanvas.com/project/658578/overview/testing-raycasts

Ok, I’ve just seen what’s the problem. I had those planes inside an entity I made earlier that it’s called Scene. I only made that entity for management because I didn’t want to have 100 or more planes in the hierarchy. It seems the raycast is hitting first this entity and it returns null, but I want to reach the planes below. Maybe I should try by changing the origin of the raycast :thinking:

I tried changing the origin point of the raycasting and still returns null.

Yes, raycastFirst will return the first rigidbody found.

If you would like to filter the context at which you are doing the raycast, look for physics groups. Those aren’t exposed in Playcanvas but Ammo supports them and potentially can be handy.

Otherwise instead of physics you could use the pc.BoundingBox class, which has its own raycast method. And you can control the list of entities you are raycasting to. Here is an example:

https://developer.playcanvas.com/en/tutorials/entity-picking-without-physics/

I want to understand sth. If I do a raycast from a point, and it finds an entity that doesn’t have collision or rigidbody, they raycast stops or keeps on until the end point?

beacuse the scene entity doesn’t have anything at all, it’s empty, so since it’s not a rigidbody nor a collision the raycast should keep until it finds a rigidbody, right?

Yes that is correct, the raycastFirst method will interact with the entities that are part of the physics simulation. That means have a collision/rigidbody component.

then my project still should work… I only made the scene entity for management so it doesnt have any rigidbody or collision components. I’m going to try making more tests to see if I make it work.

Your scene seems to be working for me, the raycast originating from the cube returns the plane entity:

yeah, in the sample project it does work perfectly, I meant in the project I want it work fine. I could try to make it public for a moment and then turn it private if it would help

Yes, either that or maybe a smaller/reduced project that replicates your issue.

https://playcanvas.com/project/656247/overview/block-builder
this is the one I’m working

the class Cube has a function called afterMove

Good, so your issue is that the raycastFirst method doesn’t accept a direction as its 2nd argument, but an end position.

https://developer.playcanvas.com/en/api/pc.RigidBodyComponentSystem.html#raycastFirst

So changing your raycasts to something like this will work:

var resultDown = this.app.systems.rigidbody.raycastFirst(from, new pc.Vec3(from.x, from.y - 10, from.z));

Just note that normally you should initialize an empty pc.Vec3 at the start of your project and reuse that, instead of allocating a new Vec3 object for each raycast as I do here. This will avoid unnecessary calls to the garbage collector.

1 Like

Omg, I can’t believe I didn’t notice that :joy:
I tried sth like that because at first I thought it was another point (end point) and not a direction, but since it wasn’t working changed my mind and I thought it was just the direction it goes.

Now the 3 planes change correctly, thank you so much for the help :grin:

1 Like

I don’t blame you, having an optional parameter to pass a direction instead of an end point would be super useful.

If you like do a feature request on the github repository for the engine about it.