0 votes

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
        $BaseMesh_Anim.move_and_slide(dir)

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 :)

A video demonstrating what it does currently: https://youtu.be/_Ifi5eJFUz4

in Engine by (134 points)

1 Answer

0 votes
Best answer

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

https://github.com/DigitalKI/GodotGridMapNav

by (134 points)
Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read Frequently asked questions and How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to webmaster@godotengine.org with your username.