Trying to figure out how Navigation works in Godot 4, it works for 3D but in 2D I'm really not sure.
Here's my current test project
I added a navigation layer to the tilemap.
I don't get any errors, but the little red dude doesn't move 🙁
Here's the code for my ennemy :
EDIT, HERE'S THE CORRECTED CODE THAT WORKS FOR ME
extends CharacterBody2D
enum state {
IDLING,
CHASING,
ATTACKING,
DEAD
}
var cur_speed : float
@export var idle_speed : float = 50
@export var chase_speed : float = 150
@export var idle_accel : float = 1
@export var chasing_accel : float = 1.5
@export var move_accel = 5
var cur_state = state.CHASING
var player = null
@onready var nav : NavigationAgent2D = $NavigationAgent2D
func _ready():
player = get_tree().get_nodes_in_group("player")[0]
func _physics_process(delta):
match cur_state:
state.IDLING:
process_state_idling(delta)
state.CHASING:
process_state_chasing(delta)
state.ATTACKING:
process_state_attacking(delta)
state.DEAD:
process_state_dead(delta)
func process_state_idling(delta):
cur_speed = move_toward(cur_speed, idle_speed, idle_accel)
func process_state_chasing(delta):
look_at(player.global_transform.origin)
cur_speed = move_toward(cur_speed, chase_speed, chasing_accel)
nav.set_target_location(player.global_position)
var direction := global_position.direction_to(nav.get_next_location())
velocity += direction * cur_speed * delta
move_and_slide()
func process_state_attacking(delta):
return
func process_state_dead(delta):
return
func set_state_idling():
cur_state = state.IDLING
func set_state_chasing():
cur_state = state.CHASING
func set_state_attacking():
cur_state = state.ATTACKING
func set_state_dead():
cur_state = state.DEAD
# Wrong original code
extends CharacterBody2D
enum state {
IDLING,
CHASING,
ATTACKING,
DEAD
}
var cur_speed : float
@export var idle_speed : float = 200
@export var chase_speed : float = 300
@export var idle_accel : float = 1
@export var chasing_accel : float = 1.5
var cur_state = state.CHASING
var player = null
@onready var nav : NavigationAgent2D = $NavigationAgent2D
var path = []
func _ready():
player = get_tree().get_nodes_in_group("player")[0]
func _physics_process(delta):
match cur_state:
state.IDLING:
process_state_idling(delta)
state.CHASING:
process_state_chasing(delta)
state.ATTACKING:
process_state_attacking(delta)
state.DEAD:
process_state_dead(delta)
func process_state_idling(delta):
cur_speed = move_toward(cur_speed, idle_speed, idle_accel)
func process_state_chasing(delta):
look_at(player.global_transform.origin)
cur_speed = move_toward(cur_speed, chase_speed, chasing_accel)
nav.set_target_location(player.global_transform.origin)
var next_path_position : Vector2 = nav.get_next_location() #get our next location to get to the point
var current_agent_position : Vector2 = global_transform.origin #get our current position
var new_velocity : Vector2 = (next_path_position - current_agent_position).normalized() * cur_speed
nav.set_velocity(new_velocity)
func process_state_attacking(delta):
return
func process_state_dead(delta):
return
func set_state_idling():
cur_state = state.IDLING
func set_state_chasing():
cur_state = state.CHASING
func set_state_attacking():
cur_state = state.ATTACKING
func set_state_dead():
cur_state = state.DEAD
func _on_navigation_agent_2d_velocity_computed(safe_velocity):
velocity = safe_velocity
move_and_slide()