-
-
Notifications
You must be signed in to change notification settings - Fork 3.6k
Description
Your Godot version:
4.6.stable.arch_linux
Issue description:
Creating NavigationLinks described in the documentation (with the link owner being set like: NavigationServer2D.link_set_owner_id(link_rid, get_instance_id())) and then reloading the scene results in the created links persisting, but losing the reference to the owner. It seems that duplicate links will also be created on each scene reload.
This can cause issues if you want to change behaviour based on the owner type (eg: Teleport links vs Jump links), as the "owner" in the metadata will be a null instance.
** To reproduce:**
- Have a script like:
class_name Teleporter extends Node2D
@export var link_start_position: Vector2
@export var link_end_position: Vector2
var link_rid: RID
func _ready() -> void:
link_rid = NavigationServer2D.link_create()
var link_owner_id: int = get_instance_id()
var link_enter_cost: float = 1.0
var link_travel_cost: float = 1.0
var link_navigation_layers: int = 1
var link_bidirectional: bool = true
NavigationServer2D.link_set_owner_id(link_rid, link_owner_id)
NavigationServer2D.link_set_enter_cost(link_rid, link_enter_cost)
NavigationServer2D.link_set_travel_cost(link_rid, link_travel_cost)
NavigationServer2D.link_set_navigation_layers(link_rid, link_navigation_layers)
NavigationServer2D.link_set_bidirectional(link_rid, link_bidirectional)
# Enable the link and set it to the default navigation map.
NavigationServer2D.link_set_enabled(link_rid, true)
NavigationServer2D.link_set_map(link_rid, get_world_2d().get_navigation_map())
# Move the 2 link positions to their intended global positions.
NavigationServer2D.link_set_start_position(link_rid, link_start_position)
NavigationServer2D.link_set_end_position(link_rid, link_end_position)
- Have a Node that uses a NavigationAgent to move
- Connect the NavigationAgent
link_reachedsignal to a function like:
func _agent_link_reached(details: Dictionary):
var link_owner = details.get("owner", null)
if link_owner == null:
# Handle missing owner
print("reached a link with no owner")
elif link_owner is Teleporter:
# Handle Teleport
print("reached a teleporter")
global_position = details.get("link_exit_position")
else:
# Handle default link type
print("reached a link with no special type")
- Add a Teleporter to the scene and navigate the agent through it. The link will work as expected on initial scene load.
- Reload the scene (eg: via
get_tree().reload_current_scene()) - Attempt to navigate through the Teleporter again, the link_owner will be null. If you check
NavigationServer2d.map_get_linksyou will see that there are now two links in the map.
** Suggested Fix **
If this is the intended behavior I think a note should be added to the documentation and perhaps add a call to NavigationServer2D.free_rid when the owner exits the tree in the example like:
func _exit_tree() -> void:
if link_rid.is_valid():
NavigationServer2D.free_rid(link_rid)
This will clear the previously created link when the scene is unloaded.
URL to the documentation page:
https://docs.godotengine.org/en/stable/tutorials/navigation/navigation_using_navigationlinks.html
If you know how to fix the issue you are reporting please
consider opening a pull request. We provide a tutorial on
using git here: https://contributing.godotengine.org/en/latest/organization/pull_requests/creating_pull_requests.html,
writing documentation at https://contributing.godotengine.org/en/latest/documentation/guidelines/index.html
and contributing to the class reference here: https://contributing.godotengine.org/en/latest/documentation/class_reference.html