3D raycast on cursor not lining up with cursor

Godot Version

4.3

Question

Hello,
Right now I have a top-down 3D world where the player can break and place blocks around them, similar to Minecraft. I followed a tutorial by xen-42 where he shows how to make this happen, and in order to aim and place blocks he used a raycast that points in front of the player.

I had to improvise since his was set up for 1st person, so I set up my raycast position and target position based off the mouse position, as shown with my code. The problem is that while the raycast follows the mouse, the target position is not directly on the cursor, and is offsetted to be below. How can I line up the raycast so blocks are broken and placed directly on the mouse?

Here’s a video to show the problem:

Here’s the code for the raycast in the player in PhysicsProcess:

Vector2 mousePosition = GetViewport().GetMousePosition();

		Vector3 rayOrigin = PlayerCamera.ProjectRayOrigin(mousePosition); // left over from before, unused
		Vector3 rayDirection = PlayerCamera.ProjectRayNormal(mousePosition);

		RayCast.GlobalPosition = PlayerCamera.GlobalPosition + rayDirection * 0.1f;
		RayCast.TargetPosition = rayDirection * 1000;

		if (RayCast.IsColliding() && RayCast.GetCollider() is Chunk chunk)
		{
			BlockHighlight.Visible = true;
			var blockPosition = RayCast.GetCollisionPoint() - 0.5f * RayCast.GetCollisionNormal(); // aims new block to be in its center with this estimate
			var intBlockPosition = new Vector3(Mathf.FloorToInt(blockPosition.X), Mathf.FloorToInt(blockPosition.Y), Mathf.FloorToInt(blockPosition.Z));
			BlockHighlight.GlobalPosition = intBlockPosition + new Vector3(0.5f, 0.5f, 0.5f);

			if (Input.IsActionJustPressed("Break"))
			{
				ChunkManager.Instance.SetBlock((Vector3I)intBlockPosition, BlockManager.Instance.Air);
			}

			if (Input.IsActionJustPressed("Place"))
			{
				ChunkManager.Instance.SetBlock((Vector3I)(intBlockPosition + RayCast.GetCollisionNormal()), BlockManager.Instance.Stone);
			}
		}
		else
		{
			BlockHighlight.Visible = false;
		}

It looks like your raycast object is child of the camera. So it should never need to move. It just needs to look in the direction of the camera projection normal. As the “eye” should be the camera origin and the raycast3d is at the cameras origin.

No whatever that red thing is in the video that points down at the selected block. That somehow is also getting used to highlight a block.

1 Like

Thanks for the catch, I got rid of the global position changes and everything still worked, although the same issue persisted. The red thing is the visible hitbox of the raycast, it was just for the sake of seeing where the raycast was actually being casted.

After tinkering for a bit, I figured it out. It turns out that the issue had to do with the camera rotation; because it was rotated -48 degrees on the x axis, I guess the raycast moved its position based on that. When I rotated the raycast +48 degrees to counter the camera, it lined up perfectly with the mouse.

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.