Moving a KinematicBody to mouse click on GridMap

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

I am creating a 3D isometric tile based game and am currently trying to get the character to “walk” to where I click. I can currently get the character to move but the vectors aren’t lining up and it walks to a different point than the mouse click.

GDScript on the Main scene:

# to aid in debug and not flooding console
var printed = false
# hold the Vector3 we're walking towards
var travel_vec = null
# speed of walking, to be tweaked
var velocity = 1

# arbitrarily large ray for picking
const raylength = 4444

# stripped down _input which basically gets the click location and stores it
func _input(_event):
	if (Input.is_mouse_button_pressed(BUTTON_LEFT)):
		var mouse_pos = get_viewport().get_mouse_position()
		var result = _get_position_from_click(mouse_pos)

# convert mouse screen position to grid map world position using an intersecting ray
func _get_position_from_click(mouse_pos):
	var from = $Camera.project_ray_origin(mouse_pos)
	var to = from + $Camera.project_ray_normal(mouse_pos) * raylength
	var space_state = MapManager.get_grid_map().get_world().direct_space_state
	var result = space_state.intersect_ray(from, to, [], 1)
	if result:
		# this is currently where I'm setting the travel vector
		# it is using the KinematicBody's y value to make sure the
		# walking stays on the same level
		var temp = $BaseMesh_Anim.global_transform.origin
		var temp2 = Vector3(result.position.x, temp.y, result.position.z)
		travel_vec = Vector3(temp2.x, temp.y, temp2.z)
		return MapManager.get_grid_map()
			.world_to_map(Vector3(result.position.x, 0, result.position.z))
func _physics_process(delta):
	# if we have a vector, walk towards it
	if (travel_vec != null):
		# set the speed based on velocity
		var dir = travel_vec.normalized() * velocity
		var temp = $BaseMesh_Anim.global_transform.origin
		if (!printed):
			print(temp, dir, travel_vec)
			printed = true
		# if the normalised vector ends up past our destination,
		# just set to our destination
		if (abs(dir.x + temp.x) > abs(travel_vec.x)):
			dir.x = travel_vec.x
			dir.z = travel_vec.z
			# set to null once we've finished moving
			travel_vec = null
		# move

The main part to figure out is the logic I’ve got in _get_position_from_click() with temp and temp2, but also the logic within _physics_process() to get the character to move. If I am way off base with how I’m doing I’d like to know now before I get further :slight_smile:

A video demonstrating what it does currently:

:bust_in_silhouette: Reply From: beaverusiv

I ended up going with a NavigationMeshInstance for the GridMap. I followed this example: