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;
}