Help with Raycast and Gridmap Cords

Godot Version

Godot Version 4.5(Steam Version)

Question

Hello!
I'm somewhat new to Godot an Im encountering a problem that I feel like im missing something.

What Im Trying to Do:
A level Editor, a raycast casts from the camera, hits the gridmap object, gets the colliding position, converts it to local_to_map, and uses set_cell to place an object.

It works completly fine, but whenever I try and place a cell in Negative Position, it no longer works as intended.

For example, These cords works fine (1, 5, 3) etc
But attempting to return for example (-5, 0, 0), it doesn't work as intended.

I'll place code and images below.

func raycast_mouse_pos():
#Get Mouse Pos
	mouse_pos = get_viewport().get_mouse_position()

#Set target pos with ray length(1000)
	raycast_mouse.target_position = pcamera.project_local_ray_normal(mouse_pos) * ray_length
	raycast_mouse.force_raycast_update()

#If colliding, update points
	if raycast_mouse.is_colliding():
#Return collision point
		collision_point = raycast_mouse.get_collision_point()
#Convert point into snapped grid
		collision_rounded = collision_point.snapped(Vector3(1, 1, 1))
#Convert snapped point into cell cords
		collision_point_cords = gridmap_objects.local_to_map(collision_rounded)
		

The Green block is where the returned value is placing.
As you can see in the bottom, it places and works fine in the positive grids.

In the Top, anything along the white(Negative) doesn’t work, and seems to snap it back to a positive. You can see the green block is inside 0,0,0, instead of the outside in the negatives.

I feel like im missing something incredibly obvious here.

Am I snapping it wrong?
Do I need to snap it?

Thank you in advance for anyone answering my questions.
I’d be happy to provide more detail if needed.

Comment out snapping. There still may be glitches if your colliders are boxes the exact size of the grid cell. Your collision points will be exactly at cell boundary and local_to_map() could screw up due to floating point precision errors, especially as you go further from the origin.

To make it more stable; get the rayhit normal as well and translate the hitpoint a bit along the direction opposite of the normal, so the point is pushed a bit “into the cell”. Then pass that to local_to_map()

I attempted this, but it still isn’t working as intended(Infact, it now only works in the negatives, but not the positives)

This is my attempted normal addition:

func raycast_mouse_pos():
	#Get Mouse Pos
	mouse_pos = get_viewport().get_mouse_position()
	
	#Set target pos with ray length(1000)
	raycast_mouse.target_position = pcamera.project_local_ray_normal(mouse_pos) * ray_length
	raycast_mouse.force_raycast_update()
	
	#If colliding, update points
	if raycast_mouse.is_colliding():
		#Return collision point
		collision_point = raycast_mouse.get_collision_point()
		collision_point_normal = raycast_mouse.get_collision_normal()
		adjust = collision_point + collision_point_normal * 0.1
		
		
		collision_point_cords = gridmap_objects.local_to_map(adjust)

I removed snapping, and replaced it with “Adjust”. Which takes collision point, and adds the normal with a multiplier of 0.1.

I’m new to normals, so Im unsure of how to approach this.

The normal points “out” from the surface so you need to go in its reverse direction if you want to push into surface:

adjust = collision_point - collision_point_normal * 0.1

Still seems to have the opposite result. I’ll attach a gif below.

helpmp4

It seems to go through the block onto the opposite side, and only able to return negative grid cords.

As you can in the gif, it now easily go into the negatives, but refuses to go into the positives. Aswell as going through the block onto the opposite side.

For context, the green blocks global position is set via the collision point cords.
And the cell is being set also by the collision point cords.

I also included the print output.

Start by making a dummy mesh instance node (e.g. a small sphere) and position it exactly at the ray hit point every frame to verify that raycasting is working properly and that you’ve got the expected position.

If your gridmap is transformed in any way you’ll need to transform the hitpoint and normal into gridmap space before doing local_to_map(). For start make sure that it has zero transforms.

I can confirm the dummysphere is correctly hitting the raycast point.
I’ll attach a gif:

helpspehere

My Gridmap scene is setup like this:
Root > GridMapHolderNode > Gridmap
All transforms for all 3 are at 0 in all Axis. Rotation is also at all 0.

Are you positioning those cubes to fit into cells? Where’s your cube’s origin point? If it’s in its center then the cube will actually cross 8 cells.

The green block is a Dummy mesh. It’s global position is set to the var collision_point_cords.
The actual placing of blocks is also set where the collision_point cords returns.

The green cubes origin point is the center.

Each mesh in the mesh library has its origin point in the center.

The gridmap size is set 1, 1, 1.
The Gridmap also has its Center XYZ turned off

I am also unsure what you mean by crossing 8 cells. Im new to gridmap sorry.

If your meshes have origin at centers then you should enable gridmap’s center property on all 3 axes

After changing the center to all axis on gridmap, the collision_point_grid now only returning 0,0,0. No matter what direction.

That sounds good. I’m assuming that you want to get the adjacent cell. In that case push the point outwards along the normal, so turn that - back into +

1 Like

It worked!
Thank you for taking your time to assist me!

3 Likes