Skip to content

Commit e9f7c18

Browse files
authored
Merge pull request #9731 from smix8/nav_agent
Add 2D versions of NavigationAgent script templates
2 parents f86bf70 + 0110340 commit e9f7c18

File tree

1 file changed

+194
-98
lines changed

1 file changed

+194
-98
lines changed

tutorials/navigation/navigation_using_navigationagents.rst

Lines changed: 194 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -142,144 +142,240 @@ to toggle avoidance. The following code snippets can be used to
142142
toggle avoidance on agents, create or delete avoidance callbacks or switch avoidance modes.
143143

144144
.. tabs::
145-
.. code-tab:: gdscript GDScript
145+
.. code-tab:: gdscript 2D GDScript
146146

147147
extends NavigationAgent2D
148148

149-
var agent: RID = get_rid()
150-
# Enable avoidance
151-
NavigationServer2D.agent_set_avoidance_enabled(agent, true)
152-
# Create avoidance callback
153-
NavigationServer2D.agent_set_avoidance_callback(agent, Callable(self, "_avoidance_done"))
149+
func _ready() -> void:
150+
var agent: RID = get_rid()
151+
# Enable avoidance
152+
NavigationServer2D.agent_set_avoidance_enabled(agent, true)
153+
# Create avoidance callback
154+
NavigationServer2D.agent_set_avoidance_callback(agent, Callable(self, "_avoidance_done"))
154155

155-
# Disable avoidance
156-
NavigationServer2D.agent_set_avoidance_enabled(agent, false)
157-
# Delete avoidance callback
158-
NavigationServer2D.agent_set_avoidance_callback(agent, Callable())
156+
# Disable avoidance
157+
NavigationServer2D.agent_set_avoidance_enabled(agent, false)
158+
# Delete avoidance callback
159+
NavigationServer2D.agent_set_avoidance_callback(agent, Callable())
159160

160-
.. tabs::
161-
.. code-tab:: gdscript GDScript
161+
.. code-tab:: gdscript 3D GDScript
162162

163163
extends NavigationAgent3D
164164

165-
var agent: RID = get_rid()
166-
# Enable avoidance
167-
NavigationServer3D.agent_set_avoidance_enabled(agent, true)
168-
# Create avoidance callback
169-
NavigationServer3D.agent_set_avoidance_callback(agent, Callable(self, "_avoidance_done"))
170-
# Switch to 3D avoidance
171-
NavigationServer3D.agent_set_use_3d_avoidance(agent, true)
172-
173-
# Disable avoidance
174-
NavigationServer3D.agent_set_avoidance_enabled(agent, false)
175-
# Delete avoidance callback
176-
NavigationServer3D.agent_set_avoidance_callback(agent, Callable())
177-
# Switch to 2D avoidance
178-
NavigationServer3D.agent_set_use_3d_avoidance(agent, false)
165+
func _ready() -> void:
166+
var agent: RID = get_rid()
167+
# Enable avoidance
168+
NavigationServer3D.agent_set_avoidance_enabled(agent, true)
169+
# Create avoidance callback
170+
NavigationServer3D.agent_set_avoidance_callback(agent, Callable(self, "_avoidance_done"))
171+
# Switch to 3D avoidance
172+
NavigationServer3D.agent_set_use_3d_avoidance(agent, true)
173+
174+
# Disable avoidance
175+
NavigationServer3D.agent_set_avoidance_enabled(agent, false)
176+
# Delete avoidance callback
177+
NavigationServer3D.agent_set_avoidance_callback(agent, Callable())
178+
# Switch to 2D avoidance
179+
NavigationServer3D.agent_set_use_3d_avoidance(agent, false)
180+
179181

180182
NavigationAgent Script Templates
181183
--------------------------------
182184

183185
The following sections provides script templates for nodes commonly used with NavigationAgents.
184186

185-
Actor as Node3D
186-
~~~~~~~~~~~~~~~
187+
.. tabs::
187188

188-
This script adds basic navigation movement to a :ref:`Node3D <class_Node3D>` with a :ref:`NavigationAgent3D <class_NavigationAgent3D>` child node.
189+
.. tab:: 2D GDScript
189190

190-
.. tabs::
191-
.. code-tab:: gdscript GDScript
191+
.. tabs::
192192

193-
extends Node3D
193+
.. code-tab:: gdscript Node2D
194194

195-
@export var movement_speed: float = 4.0
196-
@onready var navigation_agent: NavigationAgent3D = get_node("NavigationAgent3D")
197-
var movement_delta: float
195+
extends Node2D
198196

199-
func _ready() -> void:
200-
navigation_agent.velocity_computed.connect(Callable(_on_velocity_computed))
197+
@export var movement_speed: float = 4.0
198+
@onready var navigation_agent: NavigationAgent2D = get_node("NavigationAgent2D")
199+
var movement_delta: float
201200

202-
func set_movement_target(movement_target: Vector3):
203-
navigation_agent.set_target_position(movement_target)
201+
func _ready() -> void:
202+
navigation_agent.velocity_computed.connect(Callable(_on_velocity_computed))
204203

205-
func _physics_process(delta):
206-
if navigation_agent.is_navigation_finished():
207-
return
204+
func set_movement_target(movement_target: Vector2):
205+
navigation_agent.set_target_position(movement_target)
208206

209-
movement_delta = movement_speed * delta
210-
var next_path_position: Vector3 = navigation_agent.get_next_path_position()
211-
var new_velocity: Vector3 = global_position.direction_to(next_path_position) * movement_delta
212-
if navigation_agent.avoidance_enabled:
213-
navigation_agent.velocity = new_velocity
214-
else:
215-
_on_velocity_computed(new_velocity)
207+
func _physics_process(delta):
208+
# Do not query when the map has never synchronized and is empty.
209+
if NavigationServer2D.map_get_iteration_id(navigation_agent.get_navigation_map()) == 0:
210+
return
211+
if navigation_agent.is_navigation_finished():
212+
return
216213

217-
func _on_velocity_computed(safe_velocity: Vector3) -> void:
218-
global_position = global_position.move_toward(global_position + safe_velocity, movement_delta)
214+
movement_delta = movement_speed * delta
215+
var next_path_position: Vector2 = navigation_agent.get_next_path_position()
216+
var new_velocity: Vector2 = global_position.direction_to(next_path_position) * movement_delta
217+
if navigation_agent.avoidance_enabled:
218+
navigation_agent.set_velocity(new_velocity)
219+
else:
220+
_on_velocity_computed(new_velocity)
219221

220-
Actor as CharacterBody3D
221-
~~~~~~~~~~~~~~~~~~~~~~~~
222+
func _on_velocity_computed(safe_velocity: Vector2) -> void:
223+
global_position = global_position.move_toward(global_position + safe_velocity, movement_delta)
222224

223-
This script adds basic navigation movement to a :ref:`CharacterBody3D <class_CharacterBody3D>` with a :ref:`NavigationAgent3D <class_NavigationAgent3D>` child node.
225+
.. code-tab:: gdscript CharacterBody2D
224226

225-
.. tabs::
226-
.. code-tab:: gdscript GDScript
227+
extends CharacterBody2D
227228

228-
extends CharacterBody3D
229+
@export var movement_speed: float = 4.0
230+
@onready var navigation_agent: NavigationAgent2D = get_node("NavigationAgent2D")
229231

230-
@export var movement_speed: float = 4.0
231-
@onready var navigation_agent: NavigationAgent3D = get_node("NavigationAgent3D")
232+
func _ready() -> void:
233+
navigation_agent.velocity_computed.connect(Callable(_on_velocity_computed))
232234

233-
func _ready() -> void:
234-
navigation_agent.velocity_computed.connect(Callable(_on_velocity_computed))
235+
func set_movement_target(movement_target: Vector2):
236+
navigation_agent.set_target_position(movement_target)
235237

236-
func set_movement_target(movement_target: Vector3):
237-
navigation_agent.set_target_position(movement_target)
238+
func _physics_process(delta):
239+
# Do not query when the map has never synchronized and is empty.
240+
if NavigationServer2D.map_get_iteration_id(navigation_agent.get_navigation_map()) == 0:
241+
return
242+
if navigation_agent.is_navigation_finished():
243+
return
238244

239-
func _physics_process(delta):
240-
if navigation_agent.is_navigation_finished():
241-
return
245+
var next_path_position: Vector2 = navigation_agent.get_next_path_position()
246+
var new_velocity: Vector2 = global_position.direction_to(next_path_position) * movement_speed
247+
if navigation_agent.avoidance_enabled:
248+
navigation_agent.set_velocity(new_velocity)
249+
else:
250+
_on_velocity_computed(new_velocity)
242251

243-
var next_path_position: Vector3 = navigation_agent.get_next_path_position()
244-
var new_velocity: Vector3 = global_position.direction_to(next_path_position) * movement_speed
245-
if navigation_agent.avoidance_enabled:
246-
navigation_agent.velocity = new_velocity
247-
else:
248-
_on_velocity_computed(new_velocity)
252+
func _on_velocity_computed(safe_velocity: Vector2):
253+
velocity = safe_velocity
254+
move_and_slide()
249255

250-
func _on_velocity_computed(safe_velocity: Vector3):
251-
velocity = safe_velocity
252-
move_and_slide()
256+
.. code-tab:: gdscript RigidBody2D
253257

254-
Actor as RigidBody3D
255-
~~~~~~~~~~~~~~~~~~~~
258+
extends RigidBody2D
256259

257-
This script adds basic navigation movement to a :ref:`RigidBody3D <class_RigidBody3D>` with a :ref:`NavigationAgent3D <class_NavigationAgent3D>` child node.
260+
@export var movement_speed: float = 4.0
261+
@onready var navigation_agent: NavigationAgent2D = get_node("NavigationAgent2D")
258262

259-
.. tabs::
260-
.. code-tab:: gdscript GDScript
263+
func _ready() -> void:
264+
navigation_agent.velocity_computed.connect(Callable(_on_velocity_computed))
261265

262-
extends RigidBody3D
266+
func set_movement_target(movement_target: Vector2):
267+
navigation_agent.set_target_position(movement_target)
263268

264-
@export var movement_speed: float = 4.0
265-
@onready var navigation_agent: NavigationAgent3D = get_node("NavigationAgent3D")
269+
func _physics_process(delta):
270+
# Do not query when the map has never synchronized and is empty.
271+
if NavigationServer2D.map_get_iteration_id(navigation_agent.get_navigation_map()) == 0:
272+
return
273+
if navigation_agent.is_navigation_finished():
274+
return
266275

267-
func _ready() -> void:
268-
navigation_agent.velocity_computed.connect(Callable(_on_velocity_computed))
276+
var next_path_position: Vector2 = navigation_agent.get_next_path_position()
277+
var new_velocity: Vector2 = global_position.direction_to(next_path_position) * movement_speed
278+
if navigation_agent.avoidance_enabled:
279+
navigation_agent.set_velocity(new_velocity)
280+
else:
281+
_on_velocity_computed(new_velocity)
282+
283+
func _on_velocity_computed(safe_velocity: Vector2):
284+
linear_velocity = safe_velocity
285+
286+
.. tab:: 3D GDScript
287+
288+
.. tabs::
289+
290+
.. code-tab:: gdscript Node3D
291+
292+
extends Node3D
293+
294+
@export var movement_speed: float = 4.0
295+
@onready var navigation_agent: NavigationAgent3D = get_node("NavigationAgent3D")
296+
var movement_delta: float
297+
298+
func _ready() -> void:
299+
navigation_agent.velocity_computed.connect(Callable(_on_velocity_computed))
300+
301+
func set_movement_target(movement_target: Vector3):
302+
navigation_agent.set_target_position(movement_target)
303+
304+
func _physics_process(delta):
305+
# Do not query when the map has never synchronized and is empty.
306+
if NavigationServer3D.map_get_iteration_id(navigation_agent.get_navigation_map()) == 0:
307+
return
308+
if navigation_agent.is_navigation_finished():
309+
return
310+
311+
movement_delta = movement_speed * delta
312+
var next_path_position: Vector3 = navigation_agent.get_next_path_position()
313+
var new_velocity: Vector3 = global_position.direction_to(next_path_position) * movement_delta
314+
if navigation_agent.avoidance_enabled:
315+
navigation_agent.set_velocity(new_velocity)
316+
else:
317+
_on_velocity_computed(new_velocity)
318+
319+
func _on_velocity_computed(safe_velocity: Vector3) -> void:
320+
global_position = global_position.move_toward(global_position + safe_velocity, movement_delta)
321+
322+
.. code-tab:: gdscript CharacterBody3D
323+
324+
extends CharacterBody3D
325+
326+
@export var movement_speed: float = 4.0
327+
@onready var navigation_agent: NavigationAgent3D = get_node("NavigationAgent3D")
328+
329+
func _ready() -> void:
330+
navigation_agent.velocity_computed.connect(Callable(_on_velocity_computed))
331+
332+
func set_movement_target(movement_target: Vector3):
333+
navigation_agent.set_target_position(movement_target)
334+
335+
func _physics_process(delta):
336+
# Do not query when the map has never synchronized and is empty.
337+
if NavigationServer3D.map_get_iteration_id(navigation_agent.get_navigation_map()) == 0:
338+
return
339+
if navigation_agent.is_navigation_finished():
340+
return
341+
342+
var next_path_position: Vector3 = navigation_agent.get_next_path_position()
343+
var new_velocity: Vector3 = global_position.direction_to(next_path_position) * movement_speed
344+
if navigation_agent.avoidance_enabled:
345+
navigation_agent.set_velocity(new_velocity)
346+
else:
347+
_on_velocity_computed(new_velocity)
348+
349+
func _on_velocity_computed(safe_velocity: Vector3):
350+
velocity = safe_velocity
351+
move_and_slide()
352+
353+
.. code-tab:: gdscript RigidBody3D
354+
355+
extends RigidBody3D
356+
357+
@export var movement_speed: float = 4.0
358+
@onready var navigation_agent: NavigationAgent3D = get_node("NavigationAgent3D")
359+
360+
func _ready() -> void:
361+
navigation_agent.velocity_computed.connect(Callable(_on_velocity_computed))
269362

270-
func set_movement_target(movement_target: Vector3):
271-
navigation_agent.set_target_position(movement_target)
363+
func set_movement_target(movement_target: Vector3):
364+
navigation_agent.set_target_position(movement_target)
272365

273-
func _physics_process(delta):
274-
if navigation_agent.is_navigation_finished():
275-
return
366+
func _physics_process(delta):
367+
# Do not query when the map has never synchronized and is empty.
368+
if NavigationServer3D.map_get_iteration_id(navigation_agent.get_navigation_map()) == 0:
369+
return
370+
if navigation_agent.is_navigation_finished():
371+
return
276372

277-
var next_path_position: Vector3 = navigation_agent.get_next_path_position()
278-
var new_velocity: Vector3 = global_position.direction_to(next_path_position) * movement_speed
279-
if navigation_agent.avoidance_enabled:
280-
navigation_agent.velocity = new_velocity
281-
else:
282-
_on_velocity_computed(new_velocity)
373+
var next_path_position: Vector3 = navigation_agent.get_next_path_position()
374+
var new_velocity: Vector3 = global_position.direction_to(next_path_position) * movement_speed
375+
if navigation_agent.avoidance_enabled:
376+
navigation_agent.set_velocity(new_velocity)
377+
else:
378+
_on_velocity_computed(new_velocity)
283379

284-
func _on_velocity_computed(safe_velocity: Vector3):
285-
linear_velocity = safe_velocity
380+
func _on_velocity_computed(safe_velocity: Vector3):
381+
linear_velocity = safe_velocity

0 commit comments

Comments
 (0)