I've been trying to place an object in my scene where I click but I can't get it working, here's my code:

extends Camera

const ray_length = 1000
var tree_scene = load("res://src/models/Environment/Tree/adult_tree.dae")

func _input(event):
	if Input.is_action_pressed("click"):
		var ray_lenght = 1000
		var mouse_pos = get_viewport().get_mouse_pos()
		var camera = get_node("camera")
		var from = camera.project_ray_origin(mouse_pos)
		var to = from + camera.project_ray_normal(mouse_pos) * ray_length
		var space_state = get_world().get_direct_space_state()
		var result = space_state.intersect_ray( from, to )
		var tree = tree_scene.instance()
		tree.set_name("Tree")
		tree.postition(result)
		add_child(tree)

@Megalomaniak said: Shouldn't you do your raycasting in physics process?

Fair point let me try that now

Done but still not working

If I remember how raycasting works correctly, then the following code should work:

extends Camera

const ray_length = 1000
var tree_scene = preload("res://src/models/Environment/Tree/adult_tree.dae")

var perform_raycast = false

func _physics_process(_delta):
	if perform_raycast == true:
		
		# Setup a Raycast
		var ray_length = 1000
		var mouse_pos = get_viewport().get_mouse_pos()
		var camera = get_node("camera")
		var from = camera.project_ray_origin(mouse_pos)
		var to = from + camera.project_ray_normal(mouse_pos) * ray_length
		var space_state = get_world().get_direct_space_state()
		
		# Send the raycast into the scene and react if it collided with something
		var result = space_state.intersect_ray(from, to)
		# Make sure the raycast hit something...
		if result.empy() != false:
			# Make a new tree and set it's name
			var clone_tree = tree_scene.instance()
			clone_tree.name = "Tree"
			# Sometimes I've had positioning issues if I set the
			# position prior to calling add_child...
			add_child(clone_tree)
			# Change the position to the "position" key in the result dictionary.
			#
			# The position returned in the result dictionary is in world-space, so
			# we need to set the global position of the newly created tree.
			clone_tree.global_transform.origin = result["position"]
		
		perform_raycast = false

func _input(event):
	if Input.is_action_pressed("click"):
		perform_raycast = true

I added a few things, like checking if the raycast hit something or not, but the majority of the code is still the same as in your initial post. I think the reason the code in your initial post was not working is because result returns a Dictionary of data (documentation) from the raycast collision, so if you want the position, you need to use result["position"] rather than just result. (Side note: Welcome to the forums!)

@TwistedTwigleg

Haha I saw you around on other posts so I was waiting for you to come over! I'll get to testing this code now thank you!

@TwistedTwigleg

I tried the code and created an action for click and got this error "Nonexistent function 'get_mouse_pos' in base 'viewport', quick information, I am using a script to create a plane mesh and that's what the surface in the world and it is a 3D game.

@lasago said: @TwistedTwigleg

Haha I saw you around on other posts so I was waiting for you to come over! I'll get to testing this code now thank you!

No problem, happy to help B)

@lasago said: @TwistedTwigleg

I tried the code and created an action for click and got this error "Nonexistent function 'get_mouse_pos' in base 'viewport', quick information, I am using a script to create a plane mesh and that's what the surface in the world and it is a 3D game.

Hmm, maybe try replacing var mouse_pos = get_viewport().get_mouse_pos() with var mouse_pos = get_viewport().get_mouse_position(), or if that does not work then try var mouse_pos = get_tree().root.get_mouse_position.

Just to follow up in case anyone in the future has this issue and comes across this project: I was sent the project so I could debug it and after some debugging, I found what I believe was causing the issue:

  • The script is directly attached to a Camera node, so storing and using the camera was not necessary and causing the script to crash.
  • I posted a typo on line 22, it should have been if result.empty() != false:. I decided to replace it with if result.size() > 0:, though writing this now, if result.empty() != true was what I should have used when I wrote the snippet above... Ah well.
  • And then I made some minor changes specific to the project to make the code.
3 years later