How i can make an npc go to a specific target location (Position3D) using navmesh?

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

After spending the entire day trying to figure out how i can make an npc go to a specific target location i came here to find some help.
so, how i can make a npc go to a Position3D using navmesh?

are there tutorials for that?

Thanks!

Edit: i have uploaded the scene so you can take a look and tell me how i can make the cubes follow the navmesh and go to their destination
my scene: test_6 (td test)

:bust_in_silhouette: Reply From: Magso

Once the navmesh is made, reference the navigation node and use get_simple_path() which will return an array of Vector3 points. These points can be used to direct the AI by using the look_at() method and moving the AI forward in local space using xform().

I tried that but i’m new to GDscript
here is my code for the cube (enemy.tscn)

extends KinematicBody

var gravity = Vector3.DOWN * 10
var path = []
var path_ind = 0
const move_speed = 5
var velocity = Vector3()
func _ready():
	add_to_group("enemies")
	get_owner().get_simple_path(Vector3(0, 1, 0)).look_at().xform(move_speed)


func _physics_process(delta):
	velocity += gravity * delta
	velocity = move_and_slide(velocity, Vector3.UP)

I tried to reference the navigation mesh (i think i am right here)
Then i tried to get simple path
after that i tried to make it look at paths direction
and last i tried to make it move

so, what should i have done instead?
Edit I know i have done a mistake at “get_owner().get_simple_path(Vector3(0, 1, 0)).look_at().xform(move_speed)” but i don’t know how to write it correct so, what should have i done?

Giannis1996 | 2020-03-08 17:29

get_owner().get_simple_path(Vector3(0, 1, 0)).look_at().xform(move_speed) aahh!!! XD
First thing to understand is that the code like this() is a method which starts a function derived from the type - type.method(). The type can be specified by a reference to a node.

navigation_node.get_simple_path(start point, finish point, optimize true/false) #returns array of points.
spatial_node.look_at(Vector3 target point) #returns void (no usable value) but will turn the spatial node to face the target.
spatial_node.transform.xform(Vector3 direction) #returns a variant (any datatype) but in this case a Vector3 that will be in local space to the transform of the spatial node.

Here is an example of moving an AI though an array of points from get_simple_path()

export var speed : float
var point : int
onready var pathway = get_node("Navigation").get_simple_path(transform.origin, player.transform.origin, true)

func _process(delta):
    move_and_slide(global_transform.basis.xform(Vector3.FORWARD) * speed, Vector3.UP)
    look_at(pathway[point], Vector3.UP)
    if transform.origin.distance_to(pathway[point].transform.origin) <= 0.5:
        point += 1

Magso | 2020-03-08 22:47

i tried one more time and here is what i have done:

extends KinematicBody

var gravity = Vector3.DOWN * 10
var path = []
var path_ind = 0
const move_speed = 5
var velocity = Vector3()
func _ready():
	add_to_group("enemies")
	Navigation.get_simple_path($EnemySpawner, $EnemyEndpoint, true) #returns array of points.
	$Spatial.look_at(Vector3 path[path_ind]) #returns void (no usable value) but will turn the spatial node to face the target.
	$Spatial.transform.xform(Vector3 direction) #returns a variant (any datatype) but in this case a Vector3 that will be in local space to the transform of the spatial node.
	


func _physics_process(delta):
	velocity += gravity * delta
	velocity = move_and_slide(velocity, Vector3.UP)

In this time i get an Error parsing expression, misplaced: Build-In type
I stopped at “$Spatial.look_at(Vector3 path[path_ind])” just right after i got the error trying to figure out what is it
so, what is it?

Giannis1996 | 2020-03-09 08:10

There are quite a few errors in your code like $Spatial.look_at(Vector3 path[path_ind]) firstly is “Spatial” the name of a child node? Secondly the" Vector3" is not needed, in the first lot of code I was trying to tell you what types go in the brackets, these are called arguments.
examples that would work.

look_at(Vector3(10, 20, 30)) #looks at x-10, y-20, z-30 point 
look_at(transform.origin + Vector3.ONE) #looks at the node's position plus 1 on each axis.

Also the code in _physics_process won’t do anything but change the velocity variable. The return value of move_and_slide doesn’t need to be stored as a variable to work.

The look_at() and xform() are in _ready which will only execute once on the first frame, they need to be in _process or _physics_process.

Honestly, I’d advise you to look for tutorials on basic coding concepts before taking on navigation. Mainly learn about types, methods and functions and how they work together.

Magso | 2020-03-09 21:30

ok, i have done some changes to my code and now it says “non static function can only be called from an instance”

here is my code now:
extends KinematicBody

var gravity = Vector3.DOWN * 10
var path =
var path_ind = 0
const move_speed = 5
var velocity = Vector3()
func _ready():
add_to_group(“enemies”)
Navigation.get_simple_path($EnemySpawner, $EnemyEndpoint, true) #returns array of points.
look_at(path[path_ind]) #returns void (no usable value) but will turn the spatial node to face the target.
look_at(transform.origin + Vector3.ONE) #returns a variant (any datatype) but in this case a Vector3 that will be in local space to the transform of the spatial node.


why do i get that error?

Giannis1996 | 2020-03-10 08:16

Navigation is a type that has the get_simple_path()method but you’re not referencing it to anything in the scene, you’re just calling the function from the datatype rather than an instance.

Magso | 2020-03-10 22:09