How to add polygon to NavigationPolygonInstance on GDscript

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By masushin
:warning: Old Version Published before Godot 3 was released.

Please give me solution about the following issue.
Currently, I’m working on test project to study 2D navigation.
(It based on sample project "Navigation Polygon (2D)”.)

First, I have add Navigation2D node as root node.
And I have add NavigationPolygonInstance, “player” scene instance and “obstacle” scene instance to children of it.

“player” scene has been structed from KinematicBody2D which has Sprite and CollisionPolygon2D as child node.
“obstacle” scene has been structed from StaticBody2D which has Sprite and CollisionPolygon2D as child node.

For the NavigationPolygonInstance, I have add polygon like the following image preliminarily by editor.

scene

“player” has been put at top-left side.
“obstacle” has been put at right side.

NavigationPolygonInstance

And, I have add a script to Navigation2D node, like the following.

extends Navigation2D

# Member variables
const SPEED = 200.0

var begin = Vector2()
var end = Vector2()
var path = []

func _process(delta):
	if (path.size() > 1):
		var to_walk = delta*SPEED
		while(to_walk > 0 and path.size() >= 2):
			var pfrom = path[path.size() - 1]
			var pto = path[path.size() - 2]
			var d = pfrom.distance_to(pto)
			if (d <= to_walk):
				path.remove(path.size() - 1)
				to_walk -= d
			else:
				path[path.size() - 1] = pfrom.linear_interpolate(pto, to_walk/d)
				to_walk = 0
		
		var atpos = path[path.size() - 1]
		get_node("player").move_to(atpos)
		
		if (path.size() < 2):
			path = []
			set_process(false)
	else:
		set_process(false)

func _update_path():
	var new_polygon = Vector2Array()
	var col_polygon = get_node("obstacle").get_node("CollisionPolygon2D").get_polygon()

	for vector in col_polygon:
		new_polygon.append(vector + get_node("obstacle").get_pos())

	var navi_polygon = get_node("NavigationPolygonInstance").get_navigation_polygon()
	navi_polygon.add_outline(new_polygon)
	navi_polygon.make_polygons_from_outlines()

	var p = get_simple_path(begin, end, true)
	path = Array(p) # Vector2array too complex to use, convert to regular array
	path.invert()
	
	set_process(true)

func _input(event):
	if (event.type == InputEvent.MOUSE_BUTTON and event.pressed and event.button_index == 1):
		begin = get_node("player").get_pos()
		# Mouse to local navigation coordinates
		end = event.pos - get_pos()
		_update_path()

func _ready():
	set_process_input(true)

This script works like the following flow.

(1) Detects the pressing of mouse button, and get cursor position.
(2) Gets a polygon from CollisionPolygon2D of “obstacle”.
And add the polygon to NavigationPolygonInstance.
(3) Get a path by calling “get_simple_path” function.
(4) Moves “player” along the path.

In short, I want to get a path from both default NavigationPolygon and collision polygon of object which has been put on scene.

But this script does not work well.
The following GIF image shows the movement of player.

failure movement

(“Visible Navigation” of debug option is enabled.)
After the pressing of mouse button, Gray area appears around “obstacle”.
I think that it means the collision polygon of “obstacle” has been add to NavigationPolygonInstance.
But, “player” move through over the right side area. Why?

Any mistake in my code?
Or, any other procedure is needed?
Please any advice.

I’m afraid I don’t have an answer to this, but I’m playing around with doing the same in Godot 3.0 Beta 1, and I’m having the exact same issue. I can update the navmesh itself easily, but the Navigation2D node doesn’t seem to register the modified navmesh.

Rabbit | 2017-12-16 08:58

:bust_in_silhouette: Reply From: Sinsis

For anyone looking for the answer:

So here is how you get Navigation2D to recognize updates to the nav-mesh:

var navPolyInstance = $NavPolyInstance
navPolyInstance.enabled = false
navPolyInstance.enabled = true

I tried it for my own project, seems to do the trick.

A lot more info here:
https://www.reddit.com/r/godot/comments/7k4qos/why_does_this_script_created_hole_in_the/