raycastFirst - unexpected behavior and more

Hey there,
I am trying to create a raycast on a model in order to set the position of the player to the intersection point,
in more details: my land is moving and the player is moving, and I want to “project” the player on the right hight on the terrain. (meaning, the player is keeping his x and z position and the y has to change according to the terrain at this (x, ? , z).

I tried 3 different aproches but non seems to fit:

  1. in my update function of the script attached to the player, use

result = this.app.systems.rigidbody.raycastFirst(fromwhere, towhere);

problem: the result.point never changes after the first hit, allthough it is called every update
is that the expected behaviour of this function?

  1. to use a ray and intersect
    problem: I cant use a bounding box on my terrain since it is a complex shape

  2. use a collider on the player and on the terrain
    problem: it is getting a little compicated when there is no collision

(I bebuged the terrain, changed it to primitive boxes and so on, it is not due to the model I am using)

any suggestions? :disappointed_relieved:

thanks!

I would check if the from and to points are forming a ray that is hitting different parts of the terrain.

You can use a mesh for collision (be it the model mesh itself or a simplified, low poly variant).

Can you share the project to see how you have set this up so far?

hey @yaustar ,
thanks for the quick reply!!
I did check the from-to and they do create a ray, and hit the terrain, but once they did, even if the terrain is moving meaning the Y axes has changed, I keep getting the same value.
(or, if initially it doesnt hit anything, than it ignore objects that moved and are now in the hit ray)

I can use the mesh for collision and I did, as I mentioned: I can create collisions and move the player to the right location when they occur, the problem is to fit the player on the ground when there is no collision
you can see my try at the “collideVanish script” - the problem was that although I set the Restitution of both the player and the land to 0, the player kept bouncing (player is the box now instead of the 3d object).

the project is a bit messy due to all the debugging I’ve done
here is a link to the project:
https://playcanvas.com/project/494998/overview/gameprototyp
player - is a box representing the player
land - the 3d land (also has the Tag “land”)
sphere - attemp to use simple object as land
Hit-marker - object to project with the ray+bounding box solution - not relevant really

This is a VERY quick and dirty version of what you kind of want: https://playcanvas.com/project/496400/overview/gameprototyp-from-forums

I made everything static physics object for simplicity. The key thing to remember here is to use rigidbody.teleport when you want a rigidbody object to be at a set position in the world.

I had to make a workaround of the the issue with the raycast hitting the player object before the land by doing another raycast. The real solution is to write a raycast filter function that only intersects with the land.

This isn’t exposed in the Playcanvas tools but ammo.js does have support for it. Unfortunately, there isn’t any examples of this but I have done this in the past. I just can’t remember what the exact code is.

I also don’t know exactly what your end go here is so there may be some issues when you add more functionality (such as the player intersecting with the land). Rather than doing a distinct teleport, you may want to use forces to move the player around the land or perhaps you don’t even need physics on the player at all?

1 Like

@yaustar wow! ok first of all,THANK YOU so much!

do you have a min for explaining? because the changes are minor but they made the difference obviously
I did use teleport before changing it to setposition, but the problem was the result.point…
even without changing the players position, while printing out the result.point it was the same all the time:

  • so why setting the from to way higher than the player is working differently than setting it to a bit lower than the player?
  • why do you have to use the copy instead of just assigning the coordinates? (if the assignment is just creating a reference, the point should have changes also… so I’m missing something)

again, thank you!
I also dont know if this solution would cause problems in the future… we’ll see :slight_smile:

As you always want the player on the terrain, you want to create a ray using a starting point that is definitely going to be above the terrain and the end point to be definitely below it.

In your old code, you where setting the starting point below the player so it was possible that it would start below the terrain and therefore never intersect.

This is to ensure that you are not potentially changing internal data of the entity. In the old code, it was something like this:

var fromPosition = this.entity.getPosition();
fromPosition.y -= 10;

fromPosition is referencing the object that is returned from getPosition() which is internal to the entity class and therefore you are modifying that data unintentionally in the next line.

In this case, it is safer to copy the data and modify the copied data.

1 Like

@yaustar @will
I was hoping we could continue our conv about this issue:
as I said, my main goal was to “stick” the player to the land- which is moving!
The player is actually at the same location all the time, but the land is moving underneath him.

what I did (with your help) was to use a raycast, move the player to the right y axis, and than I control his rotation, collisions, animation and so on manually.

but… I think that writing my obstacles- handling manually is missing the point
I do like to somehow combine physics-collision with obstacles with my movement raycast system…
but it seems like using the teleport method each frame is messing with the physics engine
(http://answers.playcanvas.com/questions/2985/translatelocal-messing-with-rigidbodydynamic)

so… I am just making something simple into a complex thing?
is there some simple solution for this issue that I am not seeing?

thanks!

This is what I was worried about as you shouldn’t use teleport every frame if you need the rigidbody to be part of a simulation. You should only use teleport if you need to instantly move a rigidbody from one position to another.

It was only used in the example above to get you going on the raycast logic.

Without seeing the design and knowing what you intend to do in the future, it’s hard to give actual advice here beyond not using teleport.

This isn’t a straight forward problem and it really depends on the design of the app. For example, what do the obstacles do?