How to detect coordinates in 3D space? (not picking an object)

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By woopdeedoo

I’m trying to detect the x and zcoordinates of the point at which a projected line from the camera intersects with the 0 coordinate in y. My goal is to achieve something similar to this:
enter image description here(That cube isn’t being dragged, it’s being drawn at the appropriate coordinates, and its Y position is always 0)

How can I do this?


I understand how to work with raycasting, but I don’t know if and how I can use it without a collider.

I can achieve that effect with an Area (with a plane shape) and an input event signal, but then it also intersects with other physics objects that are in the scene that also have input event signals, and that seems to interfere with it.

:bust_in_silhouette: Reply From: sxkod

Will that be what you are looking for? Looks like a voxel waiting to be placed :slight_smile:

:bust_in_silhouette: Reply From: Lukaison

Check this Stack Overflow answer by Mateen Ulhaq to see how to solve a ray plane intersection. To use the code in Godot, we could do something like this:

func _input(ev):
if ev is InputEventMouseMotion:
	var camera = get_node("camera")
	var camera_from = camera.project_ray_origin(ev.position)
	var camera_to = camera.project_ray_normal(ev.position)
	
	var n = Vector3(0, 1, 0) # plane normal
	var p = camera_from # ray origin
	var v = camera_to # ray direction
	var d = 0 # distance of the plane from origin
	var t = - (n.dot(p) + d) / n.dot(v) # solving for plain/ray intersection
	
	var block_position = p + t * v

Assuming our camera node is named “camera”. If we set the translation for block to the result, it will start following the mouse. To constrain the movement to individual cells, we can divide the result by cell size and round:

	var block_size = 2
	block_position.x = round(block_position.x / block_size) * block_size
	block_position.z = round(block_position.z / block_size) * block_size
	block.translation = block_position

Sorry for my very late reply.

I ended up solving it using a plane shape, which I can also adjust to drag things in any axis. But I’ll experiment with your suggestion to see if I like it better. It seems easy enough. Also because it seems Godot will deprecate plane shapes at some point.

I also wonder if a Plane could be used there…

Thanks.

woopdeedoo | 2021-10-26 18:20