Help with NavigationLink3D.

Godot Version

Godot v.4.3 Stable

Question

I made the doors using NavigationLink3D to fix the bugs where the enemy gets stuck in the doors. The problem is that when the enemy is chasing the player, it can’t pass through the doors and gets stuck. But when it’s patrolling, it works fine. The enemy can’t collide with the doors, so it’s not a matter of getting stuck in them. I think the issue lies in the chasing state, but I’m not sure what the exact bug is. I’ll attach the enemy full code below and chase func only. Btw NavigationLink3D is always enabled and never get disabled

Full script

extends CharacterBody3D
#---------------------------------STATE MACHINE--------------------------------#
enum {
	IDLE,
	CHASE,
	CHASE_LAST,
	PATROL,
	KILL
}
var state = IDLE
var current_state = IDLE
#------------------------------------------------------------------------------#
@onready var navigation_agent: NavigationAgent3D = $NavigationAgent3D
@onready var animation_player: AnimationPlayer = $AnimationPlayer
@onready var RC: RayCast3D = $RayCast3D
@export var patrol_markers: Node3D
@export var player: CharacterBody3D

var is_waiting_for_patrol: bool = false
var player_heart_beat: bool = false
var is_patrolling: bool = true
var map_ready: bool = false
var can_kill: bool = false
var is_see: bool = false
var check: bool = false
var kill: bool = false
var last_pos: Vector3
var patrol_pos
var body = null

# Параметры движения
var movement_speed: float = 3.0
var agr = false
var rotation_speed: float = 9.0

# Для плавного поворота
var target_direction: Vector3 = Vector3.FORWARD
var current_rotation_velocity: float = 0.0


func _ready() -> void:
	await get_tree().process_frame
	map_ready = true



func _physics_process(delta):
	#--------------------------Гравитация--------------------------------------#
	if not is_on_floor():
		velocity += get_gravity() * delta
	#-----------------------------Вызов функций--------------------------------#
	anim()
	update_target_position()
	chase(delta)
	#--------------------------------------------------------------------------#

func can_see(): # проверка наличия игрока в поле зрения
	var direction = global_position.direction_to(body.global_position)
	var facing = global_transform.basis.tdotz(direction)
	var fov = cos(deg_to_rad(100))
	if facing > fov:
		is_see = true
	else:
		is_see = false

func rc(player_position: Vector3): # функция рейкаста
	var enemy_position = global_transform.origin
	RC.global_transform.origin = enemy_position
	RC.target_position = to_local(player_position)
	RC.force_raycast_update()
	
	var collider = RC.get_collider()
	return collider and collider.is_in_group("player") and is_see and check

func _on_timer_timeout() -> void: # перезарядка рейкаста
	if check:
		can_see()
	if rc(player.position):
		RC.debug_shape_custom_color = Color(0, 200, 0)
		state = CHASE
		current_state = CHASE
		if can_kill:
			get_tree().change_scene_to_file("res://Scenes/death_screen.tscn")
	else:
		RC.debug_shape_custom_color = Color(200, 0, 0)
		if current_state == CHASE:
			last_pos = player.global_position
			await get_tree().create_timer(2, false).timeout
			state = CHASE_LAST
			current_state = CHASE_LAST
		else:
			if velocity == Vector3.ZERO and !is_waiting_for_patrol:
				state = PATROL
	if state == PATROL and velocity == Vector3.ZERO and !is_waiting_for_patrol:
		is_waiting_for_patrol = true
		state = IDLE
		if !agr:
			await  get_tree().create_timer(5).timeout
		is_waiting_for_patrol = false
		if state == IDLE:
			is_patrolling = true
			state = PATROL


func chase(delta):
	if not map_ready:
		return
	if navigation_agent.is_navigation_finished():
		velocity = Vector3.ZERO
		return
	
	var current_position: Vector3 = global_position
	var next_position: Vector3 = navigation_agent.get_next_path_position()
	
	var direction = current_position.direction_to(next_position)
	var horizontal_direction = Vector3(direction.x, 0, direction.z).normalized()
	var target_angle = atan2(horizontal_direction.x, horizontal_direction.z)
	rotation.y = lerp_angle(rotation.y, target_angle, delta * rotation_speed)
	
	velocity = direction * movement_speed
	move_and_slide()


func anim():
	if !kill:
		match state:
			IDLE:
				animation_player.play("idle")
				player_heart_beat = false
			CHASE:
				animation_player.play("run")
				player_heart_beat = true
			CHASE_LAST:
				animation_player.play("run")
			PATROL:
				if agr:
					animation_player.play("run_2")
				else:
					animation_player.play("walk")
				player_heart_beat = false


func update_target_position():
	match state:
		CHASE:
			navigation_agent.target_position = player.global_position
			movement_speed = 4.8
			if agr: 
				movement_speed = 5.2
		CHASE_LAST:
			navigation_agent.target_position = last_pos
		PATROL:
			if is_patrolling:
				is_patrolling = false
				if agr:
					movement_speed = 5.2
				else:
					movement_speed = 3.0
				patrol_pos = get_random_patrol_pos(patrol_markers)
				navigation_agent.target_position = patrol_pos.position


func get_random_patrol_pos(parent: Node3D) -> Node:
	var child_count = parent.get_child_count()
	if child_count == 0:
		return null
	var random_index = randi() % child_count
	return parent.get_child(random_index)


func _kill():
	kill = true
	state = KILL
	animation_player.play("kill")
	velocity = Vector3.ZERO
	await  animation_player.animation_finished


func _on_ray_area_body_entered(_body: Node3D) -> void:
	if _body.name == "Player":
		check = true
		body = _body

func _on_ray_area_body_exited(_body: Node3D) -> void:
	if _body.name == "Player":
		check = false
		body = null


func _on_area_3d_body_entered(_body: Node3D) -> void:
	if _body.name == "Player":
		can_kill = true

func _on_area_3d_body_exited(_body: Node3D) -> void:
	if _body.name == "Player":
		can_kill = false

Chase func only

func chase(delta):
	if not map_ready:
		return
	if navigation_agent.is_navigation_finished():
		velocity = Vector3.ZERO
		return
	
	var current_position: Vector3 = global_position
	var next_position: Vector3 = navigation_agent.get_next_path_position()
	
	var direction = current_position.direction_to(next_position)
	var horizontal_direction = Vector3(direction.x, 0, direction.z).normalized()
	var target_angle = atan2(horizontal_direction.x, horizontal_direction.z)
	rotation.y = lerp_angle(rotation.y, target_angle, delta * rotation_speed)
	
	velocity = direction * movement_speed
	move_and_slide()

func update_target_position():
	match state:
		CHASE:
			navigation_agent.target_position = player.global_position
			movement_speed = 4.8
			if agr: 
				movement_speed = 5.2
		CHASE_LAST:
			navigation_agent.target_position = last_pos
		PATROL:
			if is_patrolling:
				is_patrolling = false
				if agr:
					movement_speed = 5.2
				else:
					movement_speed = 3.0
				patrol_pos = get_random_patrol_pos(patrol_markers)
				navigation_agent.target_position = patrol_pos.position

Try to disable Collisonshape completely and see if it gets stuck.