0
\$\begingroup\$

How do I know if a node is in within a navigation rectangle? I am working on an enemy spawner that puts enemies off screen but I need to pick positions where the enemies will actually work (read: on a navigation area).

(Originally asked on Discord.)

\$\endgroup\$

1 Answer 1

3
\$\begingroup\$

I'd find the closest point (NavigationServer3D.map_get_closest_point()) and check the distance between them. If it's on the map, the distance would be approximately zero.

Also, that likely gives you a valid spawn position. You could also push in away from original point to spawn away from area edge!

Something like this:

func get_point_on_map(target_point: Vector3, min_dist_from_edge: float) -> Vector3:
    var map := get_world_3d().navigation_map
    var closest_point := NavigationServer3D.map_get_closest_point(map, target_point)
    var delta := closest_point - target_point
    var is_on_map = delta.is_zero_approx()  # Answer to original question!
    if not is_on_map and min_dist_from_edge > 0:
        # Wasn't on the map, so push in from edge. If you have thin sections on
        # your navmesh, this could push it back off the navmesh!
        delta = delta.normalized()
        closest_point += delta * min_dist_from_edge
    return closest_point

Something similar should also work for 2D.

You could probably also get the nav mesh polygons and do an inside polygon test, but that's probably slower and more hassle.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .