1
\$\begingroup\$

I'm trying to make navigation possible for npcs in a 2D platformer.

The game generates chunks with random platforms as the player ascends, so I also need to implement the navigation procedurally.

Each chunk is a square of 192x192px, so first I create a square shaped outline (clockwise) that conforms all the chunk:

    var new_2d_region_rid: RID = NavigationServer2D.region_create()
    var default_2d_map_rid: RID = get_world_2d().get_navigation_map()
    NavigationServer2D.region_set_map(new_2d_region_rid, default_2d_map_rid)

    var chunk_outline := PackedVector2Array([
        Vector2(0.0, current_chunk_row),
        Vector2(CHUNK_SIZE.x, current_chunk_row),
        Vector2(CHUNK_SIZE.x, current_chunk_row + CHUNK_SIZE.y),
        Vector2(0.0, current_chunk_row + CHUNK_SIZE.y),
    ])

Then, my intention is to clip or substract the platforms (obstacles) from that outline. Platforms for the new chunk are stored in an Array[PackedVector2Array] clockwise:

    var ccw_outlines: Array[PackedVector2Array] = []
    for platform in platforms_of_new_chunk:
        var clipped_outlines := Geometry2D.clip_polygons(chunk_outline, platform)
        # save the holes for later
        for clipped_outline in clipped_outlines:
            # holes are CCW from Geometry2D.clip_polygons
            if not Geometry2D.is_polygon_clockwise(clipped_outline):
                ccw_outlines.push_back(clipped_outline)

Lastly I create the NavigationPolygon:

    var new_navigation_polygon := NavigationPolygon.new()
    new_navigation_polygon.add_outline(chunk_outline) # the big one covering the whole chunk
    for outline in ccw_outlines:
        outline.reverse() # I reverse this to make them CW, b/c error msg says so
        new_navigation_polygon.add_outline(outline)
    new_navigation_polygon.make_polygons_from_outlines()
    
    NavigationServer2D.region_set_navigation_polygon(new_2d_region_rid, new_navigation_polygon)

This gives me 2 error messages and obviously no platform avoiding navigation:

E 0:00:00:0962 sync: Navigation map synchronization error. Attempted to merge a navigation mesh polygon edge with another already-merged edge. This is usually caused by crossing edges, overlapping polygons, or a mismatch of the NavigationMesh / NavigationPolygon baked 'cell_size' and navigation map 'cell_size'. <C++ Source>
modules/navigation/nav_map.cpp:845 @ sync()

And (emphasis mine):

E 0:00:12:0220 level.gd:102 @ generate_navigation_region(): NavigationPolygon: Convex partition failed! Failed to convert outlines to a valid NavigationMesh. NavigationPolygon outlines can not overlap vertices or edges inside same outline or with other outlines or have any intersections. Add the outmost and largest outline first. To add holes inside this outline add the smaller outlines with same winding order. <C++ Source> scene/resources/navigation_polygon.cpp:296 @ make_polygons_from_outlines() level.gd:102 @ generate_navigation_region() level.gd:63 @ generate_chunks() level.gd:189 @ _on_area_2d_body_entered()

I think I'm doing it as the error suggests. What could be wrong? Or maybe there's another way to achieve what I want.

\$\endgroup\$

0

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.