+1 vote

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: https://www.mediafire.com/file/p4rlzoptklal9yq/test_6_%28td_test%29.rar/file

in Engine by (67 points)
edited by

1 Answer

+2 votes

Once the navmesh is made, reference the navigation node and use getsimplepath() 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().

by (3,227 points)

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 "getowner().getsimplepath(Vector3(0, 1, 0)).lookat().xform(move_speed)" but i don't know how to write it correct so, what should have i done?

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

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.lookat(Vector3 path[pathind])" just right after i got the error trying to figure out what is it
so, what is it?

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.

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 pathind = 0
const move
speed = 5
var velocity = Vector3()
func ready():
add
togroup("enemies")
Navigation.get
simplepath($EnemySpawner, $EnemyEndpoint, true) #returns array of points.
look
at(path[pathind]) #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?

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.

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 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.