From cfdfd304f1ad08b0498eda97b502aaccd95f559d Mon Sep 17 00:00:00 2001 From: smix8 <52464204+smix8@users.noreply.github.com> Date: Mon, 6 Jun 2022 05:24:11 +0200 Subject: [PATCH] Add NavigationRegion costs for pathfinding Add NavigationRegion costs for pathfinding. --- doc/classes/NavigationRegion2D.xml | 9 ++++++ doc/classes/NavigationRegion3D.xml | 10 +++++++ doc/classes/NavigationServer2D.xml | 30 +++++++++++++++++++ doc/classes/NavigationServer3D.xml | 30 +++++++++++++++++++ .../navigation/godot_navigation_server.cpp | 30 +++++++++++++++++++ modules/navigation/godot_navigation_server.h | 6 ++++ modules/navigation/nav_map.cpp | 16 ++++++++-- modules/navigation/nav_region.h | 8 +++++ scene/2d/navigation_region_2d.cpp | 30 +++++++++++++++++++ scene/2d/navigation_region_2d.h | 9 ++++++ scene/3d/navigation_region_3d.cpp | 30 +++++++++++++++++++ scene/3d/navigation_region_3d.h | 9 ++++++ servers/navigation_server_2d.cpp | 10 +++++++ servers/navigation_server_2d.h | 8 +++++ servers/navigation_server_3d.cpp | 4 +++ servers/navigation_server_3d.h | 8 +++++ 16 files changed, 244 insertions(+), 3 deletions(-) diff --git a/doc/classes/NavigationRegion2D.xml b/doc/classes/NavigationRegion2D.xml index 5cd2e035b65f..542aa8f61997 100644 --- a/doc/classes/NavigationRegion2D.xml +++ b/doc/classes/NavigationRegion2D.xml @@ -7,6 +7,9 @@ A region of the navigation map. It tells the [NavigationServer2D] what can be navigated and what cannot, based on its [NavigationPolygon] resource. Two regions can be connected to each other if they share a similar edge. You can set the minimum distance between two vertices required to connect two edges by using [method NavigationServer2D.map_set_edge_connection_margin]. [b]Note:[/b] Overlapping two regions' polygons is not enough for connecting two regions. They must share a similar edge. + The pathfinding cost of entering this region from another region can be controlled with the [member enter_cost] value. + [b]Note[/b]: This value is not added to the path cost when the start position is already inside this region. + The pathfinding cost of traveling distances inside this region can be controlled with the [member travel_cost] multiplier. @@ -22,11 +25,17 @@ Determines if the [NavigationRegion2D] is enabled or disabled. + + When pathfinding enters this regions navmesh from another regions navmesh the [code]enter_cost[/code] value is added to the path distance for determining the shortest path. + A bitfield determining all layers the region belongs to. These layers can be checked upon when requesting a path with [method NavigationServer2D.map_get_path]. The [NavigationPolygon] resource to use. + + When pathfinding moves inside this regions navmesh the traveled distances are multiplied with [code]travel_cost[/code] for determining the shortest path. + diff --git a/doc/classes/NavigationRegion3D.xml b/doc/classes/NavigationRegion3D.xml index 42f0e0c5d9cd..e45bca7f8ba1 100644 --- a/doc/classes/NavigationRegion3D.xml +++ b/doc/classes/NavigationRegion3D.xml @@ -6,6 +6,10 @@ A region of the navigation map. It tells the [NavigationServer3D] what can be navigated and what cannot, based on its [NavigationMesh] resource. Two regions can be connected to each other if they share a similar edge. You can set the minimum distance between two vertices required to connect two edges by using [method NavigationServer3D.map_set_edge_connection_margin]. + [b]Note:[/b] Overlapping two regions' navmeshes is not enough for connecting two regions. They must share a similar edge. + The cost of entering this region from another region can be controlled with the [member enter_cost] value. + [b]Note[/b]: This value is not added to the path cost when the start position is already inside this region. + The cost of traveling distances inside this region can be controlled with the [member travel_cost] multiplier. @@ -28,12 +32,18 @@ Determines if the [NavigationRegion3D] is enabled or disabled. + + When pathfinding enters this regions navmesh from another regions navmesh the [code]enter_cost[/code] value is added to the path distance for determining the shortest path. + A bitfield determining all layers the region belongs to. These layers can be checked upon when requesting a path with [method NavigationServer3D.map_get_path]. The [NavigationMesh] resource to use. + + When pathfinding moves inside this regions navmesh the traveled distances are multiplied with [code]travel_cost[/code] for determining the shortest path. + diff --git a/doc/classes/NavigationServer2D.xml b/doc/classes/NavigationServer2D.xml index 1994a7a4c466..7b0dac99c3d9 100644 --- a/doc/classes/NavigationServer2D.xml +++ b/doc/classes/NavigationServer2D.xml @@ -247,6 +247,13 @@ Returns how many connections this [code]region[/code] has with other regions in the map. + + + + + Returns the [code]enter_cost[/code] of this [code]region[/code]. + + @@ -261,6 +268,21 @@ Returns the navigation map [RID] the requested [code]region[/code] is currently assigned to. + + + + + Returns the [code]travel_cost[/code] of this [code]region[/code]. + + + + + + + + Sets the [code]enter_cost[/code] for this [code]region[/code]. + + @@ -293,6 +315,14 @@ Sets the global transformation for the region. + + + + + + Sets the [code]travel_cost[/code] for this [code]region[/code]. + + diff --git a/doc/classes/NavigationServer3D.xml b/doc/classes/NavigationServer3D.xml index 2a729e71083d..d6574dd69a71 100644 --- a/doc/classes/NavigationServer3D.xml +++ b/doc/classes/NavigationServer3D.xml @@ -297,6 +297,13 @@ Returns how many connections this [code]region[/code] has with other regions in the map. + + + + + Returns the [code]enter_cost[/code] of this [code]region[/code]. + + @@ -311,6 +318,21 @@ Returns the navigation map [RID] the requested [code]region[/code] is currently assigned to. + + + + + Returns the [code]travel_cost[/code] of this [code]region[/code]. + + + + + + + + Sets the [code]enter_cost[/code] for this [code]region[/code]. + + @@ -343,6 +365,14 @@ Sets the global transformation for the region. + + + + + + Sets the [code]travel_cost[/code] for this [code]region[/code]. + + diff --git a/modules/navigation/godot_navigation_server.cpp b/modules/navigation/godot_navigation_server.cpp index cc9d05da4792..f4e719b0c17a 100644 --- a/modules/navigation/godot_navigation_server.cpp +++ b/modules/navigation/godot_navigation_server.cpp @@ -309,6 +309,36 @@ COMMAND_2(region_set_transform, RID, p_region, Transform3D, p_transform) { region->set_transform(p_transform); } +COMMAND_2(region_set_enter_cost, RID, p_region, real_t, p_enter_cost) { + NavRegion *region = region_owner.get_or_null(p_region); + ERR_FAIL_COND(region == nullptr); + ERR_FAIL_COND(p_enter_cost < 0.0); + + region->set_enter_cost(p_enter_cost); +} + +real_t GodotNavigationServer::region_get_enter_cost(RID p_region) const { + NavRegion *region = region_owner.get_or_null(p_region); + ERR_FAIL_COND_V(region == nullptr, 0); + + return region->get_enter_cost(); +} + +COMMAND_2(region_set_travel_cost, RID, p_region, real_t, p_travel_cost) { + NavRegion *region = region_owner.get_or_null(p_region); + ERR_FAIL_COND(region == nullptr); + ERR_FAIL_COND(p_travel_cost < 0.0); + + region->set_travel_cost(p_travel_cost); +} + +real_t GodotNavigationServer::region_get_travel_cost(RID p_region) const { + NavRegion *region = region_owner.get_or_null(p_region); + ERR_FAIL_COND_V(region == nullptr, 0); + + return region->get_travel_cost(); +} + COMMAND_2(region_set_layers, RID, p_region, uint32_t, p_layers) { NavRegion *region = region_owner.get_or_null(p_region); ERR_FAIL_COND(region == nullptr); diff --git a/modules/navigation/godot_navigation_server.h b/modules/navigation/godot_navigation_server.h index 89e7311e51fb..1a7fddb7e673 100644 --- a/modules/navigation/godot_navigation_server.h +++ b/modules/navigation/godot_navigation_server.h @@ -109,6 +109,12 @@ class GodotNavigationServer : public NavigationServer3D { virtual Array map_get_agents(RID p_map) const override; virtual RID region_create() const override; + + COMMAND_2(region_set_enter_cost, RID, p_region, real_t, p_enter_cost); + virtual real_t region_get_enter_cost(RID p_region) const override; + COMMAND_2(region_set_travel_cost, RID, p_region, real_t, p_travel_cost); + virtual real_t region_get_travel_cost(RID p_region) const override; + COMMAND_2(region_set_map, RID, p_region, RID, p_map); virtual RID region_get_map(RID p_region) const override; COMMAND_2(region_set_layers, RID, p_region, uint32_t, p_layers); diff --git a/modules/navigation/nav_map.cpp b/modules/navigation/nav_map.cpp index 344475fb377e..059dc989a871 100644 --- a/modules/navigation/nav_map.cpp +++ b/modules/navigation/nav_map.cpp @@ -140,6 +140,8 @@ Vector NavMap::get_path(Vector3 p_origin, Vector3 p_destination, bool p float reachable_d = 1e30; bool is_reachable = true; + gd::NavigationPoly *prev_least_cost_poly = nullptr; + while (true) { // Takes the current least_cost_poly neighbors (iterating over its edges) and compute the traveled_distance. for (size_t i = 0; i < navigation_polys[least_cost_id].poly->edges.size(); i++) { @@ -156,9 +158,17 @@ Vector NavMap::get_path(Vector3 p_origin, Vector3 p_destination, bool p continue; } + float region_enter_cost = 0.0; + float region_travel_cost = least_cost_poly->poly->owner->get_travel_cost(); + + if (prev_least_cost_poly != nullptr && !(prev_least_cost_poly->poly->owner->get_self() == least_cost_poly->poly->owner->get_self())) { + region_enter_cost = least_cost_poly->poly->owner->get_enter_cost(); + } + prev_least_cost_poly = least_cost_poly; + Vector3 pathway[2] = { connection.pathway_start, connection.pathway_end }; const Vector3 new_entry = Geometry3D::get_closest_point_to_segment(least_cost_poly->entry, pathway); - const float new_distance = least_cost_poly->entry.distance_to(new_entry) + least_cost_poly->traveled_distance; + const float new_distance = (least_cost_poly->entry.distance_to(new_entry) * region_travel_cost) + region_enter_cost + least_cost_poly->traveled_distance; const std::vector::iterator it = std::find( navigation_polys.begin(), @@ -238,7 +248,7 @@ Vector NavMap::get_path(Vector3 p_origin, Vector3 p_destination, bool p for (List::Element *element = to_visit.front(); element != nullptr; element = element->next()) { gd::NavigationPoly *np = &navigation_polys[element->get()]; float cost = np->traveled_distance; - cost += np->entry.distance_to(end_point); + cost += (np->entry.distance_to(end_point) * np->poly->owner->get_travel_cost()); if (cost < least_cost) { least_cost_id = np->self_id; least_cost = cost; @@ -249,7 +259,7 @@ Vector NavMap::get_path(Vector3 p_origin, Vector3 p_destination, bool p // Stores the further reachable end polygon, in case our goal is not reachable. if (is_reachable) { - float d = navigation_polys[least_cost_id].entry.distance_to(p_destination); + float d = navigation_polys[least_cost_id].entry.distance_to(p_destination) * navigation_polys[least_cost_id].poly->owner->get_travel_cost(); if (reachable_d > d) { reachable_d = d; reachable_end = navigation_polys[least_cost_id].poly; diff --git a/modules/navigation/nav_region.h b/modules/navigation/nav_region.h index 7a6da281c088..acde5de834e7 100644 --- a/modules/navigation/nav_region.h +++ b/modules/navigation/nav_region.h @@ -46,6 +46,8 @@ class NavRegion : public NavRid { Transform3D transform; Ref mesh; uint32_t layers = 1; + float enter_cost = 0.0; + float travel_cost = 1.0; Vector connections; bool polygons_dirty = true; @@ -65,6 +67,12 @@ class NavRegion : public NavRid { return map; } + void set_enter_cost(float p_enter_cost) { enter_cost = MAX(p_enter_cost, 0.0); } + float get_enter_cost() const { return enter_cost; } + + void set_travel_cost(float p_travel_cost) { travel_cost = MAX(p_travel_cost, 0.0); } + float get_travel_cost() const { return travel_cost; } + void set_layers(uint32_t p_layers); uint32_t get_layers() const; diff --git a/scene/2d/navigation_region_2d.cpp b/scene/2d/navigation_region_2d.cpp index 41773d81c576..6f3222f27e1a 100644 --- a/scene/2d/navigation_region_2d.cpp +++ b/scene/2d/navigation_region_2d.cpp @@ -388,6 +388,26 @@ uint32_t NavigationRegion2D::get_layers() const { return NavigationServer2D::get_singleton()->region_get_layers(region); } +void NavigationRegion2D::set_enter_cost(real_t p_enter_cost) { + ERR_FAIL_COND_MSG(p_enter_cost < 0.0, "The enter_cost must be positive."); + enter_cost = MAX(p_enter_cost, 0.0); + NavigationServer2D::get_singleton()->region_set_enter_cost(region, p_enter_cost); +} + +real_t NavigationRegion2D::get_enter_cost() const { + return enter_cost; +} + +void NavigationRegion2D::set_travel_cost(real_t p_travel_cost) { + ERR_FAIL_COND_MSG(p_travel_cost < 0.0, "The travel_cost must be positive."); + travel_cost = MAX(p_travel_cost, 0.0); + NavigationServer2D::get_singleton()->region_set_enter_cost(region, travel_cost); +} + +real_t NavigationRegion2D::get_travel_cost() const { + return travel_cost; +} + RID NavigationRegion2D::get_region_rid() const { return region; } @@ -544,16 +564,26 @@ void NavigationRegion2D::_bind_methods() { ClassDB::bind_method(D_METHOD("get_region_rid"), &NavigationRegion2D::get_region_rid); + ClassDB::bind_method(D_METHOD("set_enter_cost", "enter_cost"), &NavigationRegion2D::set_enter_cost); + ClassDB::bind_method(D_METHOD("get_enter_cost"), &NavigationRegion2D::get_enter_cost); + + ClassDB::bind_method(D_METHOD("set_travel_cost", "travel_cost"), &NavigationRegion2D::set_travel_cost); + ClassDB::bind_method(D_METHOD("get_travel_cost"), &NavigationRegion2D::get_travel_cost); + ClassDB::bind_method(D_METHOD("_navpoly_changed"), &NavigationRegion2D::_navpoly_changed); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "navpoly", PROPERTY_HINT_RESOURCE_TYPE, "NavigationPolygon"), "set_navigation_polygon", "get_navigation_polygon"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "enabled"), "set_enabled", "is_enabled"); ADD_PROPERTY(PropertyInfo(Variant::INT, "layers", PROPERTY_HINT_LAYERS_2D_NAVIGATION), "set_layers", "get_layers"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "enter_cost"), "set_enter_cost", "get_enter_cost"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "travel_cost"), "set_travel_cost", "get_travel_cost"); } NavigationRegion2D::NavigationRegion2D() { set_notify_transform(true); region = NavigationServer2D::get_singleton()->region_create(); + NavigationServer2D::get_singleton()->region_set_enter_cost(region, get_enter_cost()); + NavigationServer2D::get_singleton()->region_set_travel_cost(region, get_travel_cost()); } NavigationRegion2D::~NavigationRegion2D() { diff --git a/scene/2d/navigation_region_2d.h b/scene/2d/navigation_region_2d.h index 3c4a4e81d989..31574749f7b9 100644 --- a/scene/2d/navigation_region_2d.h +++ b/scene/2d/navigation_region_2d.h @@ -98,6 +98,9 @@ class NavigationRegion2D : public Node2D { RID region; Ref navpoly; + real_t enter_cost = 0.0; + real_t travel_cost = 1.0; + void _navpoly_changed(); void _map_changed(RID p_RID); @@ -119,6 +122,12 @@ class NavigationRegion2D : public Node2D { RID get_region_rid() const; + void set_enter_cost(real_t p_enter_cost); + real_t get_enter_cost() const; + + void set_travel_cost(real_t p_travel_cost); + real_t get_travel_cost() const; + void set_navigation_polygon(const Ref &p_navpoly); Ref get_navigation_polygon() const; diff --git a/scene/3d/navigation_region_3d.cpp b/scene/3d/navigation_region_3d.cpp index cb8da182eeab..dda138281475 100644 --- a/scene/3d/navigation_region_3d.cpp +++ b/scene/3d/navigation_region_3d.cpp @@ -73,6 +73,26 @@ uint32_t NavigationRegion3D::get_layers() const { return NavigationServer3D::get_singleton()->region_get_layers(region); } +void NavigationRegion3D::set_enter_cost(real_t p_enter_cost) { + ERR_FAIL_COND_MSG(p_enter_cost < 0.0, "The enter_cost must be positive."); + enter_cost = MAX(p_enter_cost, 0.0); + NavigationServer3D::get_singleton()->region_set_enter_cost(region, p_enter_cost); +} + +real_t NavigationRegion3D::get_enter_cost() const { + return enter_cost; +} + +void NavigationRegion3D::set_travel_cost(real_t p_travel_cost) { + ERR_FAIL_COND_MSG(p_travel_cost < 0.0, "The travel_cost must be positive."); + travel_cost = MAX(p_travel_cost, 0.0); + NavigationServer3D::get_singleton()->region_set_enter_cost(region, travel_cost); +} + +real_t NavigationRegion3D::get_travel_cost() const { + return travel_cost; +} + RID NavigationRegion3D::get_region_rid() const { return region; } @@ -224,12 +244,20 @@ void NavigationRegion3D::_bind_methods() { ClassDB::bind_method(D_METHOD("get_region_rid"), &NavigationRegion3D::get_region_rid); + ClassDB::bind_method(D_METHOD("set_enter_cost", "enter_cost"), &NavigationRegion3D::set_enter_cost); + ClassDB::bind_method(D_METHOD("get_enter_cost"), &NavigationRegion3D::get_enter_cost); + + ClassDB::bind_method(D_METHOD("set_travel_cost", "travel_cost"), &NavigationRegion3D::set_travel_cost); + ClassDB::bind_method(D_METHOD("get_travel_cost"), &NavigationRegion3D::get_travel_cost); + ClassDB::bind_method(D_METHOD("bake_navigation_mesh", "on_thread"), &NavigationRegion3D::bake_navigation_mesh, DEFVAL(true)); ClassDB::bind_method(D_METHOD("_bake_finished", "nav_mesh"), &NavigationRegion3D::_bake_finished); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "navmesh", PROPERTY_HINT_RESOURCE_TYPE, "NavigationMesh"), "set_navigation_mesh", "get_navigation_mesh"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "enabled"), "set_enabled", "is_enabled"); ADD_PROPERTY(PropertyInfo(Variant::INT, "layers", PROPERTY_HINT_LAYERS_3D_NAVIGATION), "set_layers", "get_layers"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "enter_cost"), "set_enter_cost", "get_enter_cost"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "travel_cost"), "set_travel_cost", "get_travel_cost"); ADD_SIGNAL(MethodInfo("navigation_mesh_changed")); ADD_SIGNAL(MethodInfo("bake_finished")); @@ -243,6 +271,8 @@ void NavigationRegion3D::_navigation_changed() { NavigationRegion3D::NavigationRegion3D() { set_notify_transform(true); region = NavigationServer3D::get_singleton()->region_create(); + NavigationServer3D::get_singleton()->region_set_enter_cost(region, get_enter_cost()); + NavigationServer3D::get_singleton()->region_set_travel_cost(region, get_travel_cost()); } NavigationRegion3D::~NavigationRegion3D() { diff --git a/scene/3d/navigation_region_3d.h b/scene/3d/navigation_region_3d.h index 140dfebf6afb..042684c5b7b5 100644 --- a/scene/3d/navigation_region_3d.h +++ b/scene/3d/navigation_region_3d.h @@ -41,6 +41,9 @@ class NavigationRegion3D : public Node3D { RID region; Ref navmesh; + real_t enter_cost = 0.0; + real_t travel_cost = 1.0; + Node *debug_view = nullptr; Thread bake_thread; @@ -59,6 +62,12 @@ class NavigationRegion3D : public Node3D { RID get_region_rid() const; + void set_enter_cost(real_t p_enter_cost); + real_t get_enter_cost() const; + + void set_travel_cost(real_t p_travel_cost); + real_t get_travel_cost() const; + void set_navigation_mesh(const Ref &p_navmesh); Ref get_navigation_mesh() const; diff --git a/servers/navigation_server_2d.cpp b/servers/navigation_server_2d.cpp index 901d33501724..ab323e76e8dc 100644 --- a/servers/navigation_server_2d.cpp +++ b/servers/navigation_server_2d.cpp @@ -174,6 +174,10 @@ void NavigationServer2D::_bind_methods() { ClassDB::bind_method(D_METHOD("map_get_agents", "map"), &NavigationServer2D::map_get_agents); ClassDB::bind_method(D_METHOD("region_create"), &NavigationServer2D::region_create); + ClassDB::bind_method(D_METHOD("region_set_enter_cost", "region", "enter_cost"), &NavigationServer2D::region_set_enter_cost); + ClassDB::bind_method(D_METHOD("region_get_enter_cost", "region"), &NavigationServer2D::region_get_enter_cost); + ClassDB::bind_method(D_METHOD("region_set_travel_cost", "region", "travel_cost"), &NavigationServer2D::region_set_travel_cost); + ClassDB::bind_method(D_METHOD("region_get_travel_cost", "region"), &NavigationServer2D::region_get_travel_cost); ClassDB::bind_method(D_METHOD("region_set_map", "region", "map"), &NavigationServer2D::region_set_map); ClassDB::bind_method(D_METHOD("region_get_map", "region"), &NavigationServer2D::region_get_map); ClassDB::bind_method(D_METHOD("region_set_layers", "region", "layers"), &NavigationServer2D::region_set_layers); @@ -239,6 +243,12 @@ Vector2 FORWARD_2_R_C(v3_to_v2, map_get_closest_point, RID, p_map, const Vector2 RID FORWARD_2_C(map_get_closest_point_owner, RID, p_map, const Vector2 &, p_point, rid_to_rid, v2_to_v3); RID FORWARD_0_C(region_create); + +void FORWARD_2_C(region_set_enter_cost, RID, p_region, real_t, p_enter_cost, rid_to_rid, real_to_real); +real_t FORWARD_1_C(region_get_enter_cost, RID, p_region, rid_to_rid); +void FORWARD_2_C(region_set_travel_cost, RID, p_region, real_t, p_travel_cost, rid_to_rid, real_to_real); +real_t FORWARD_1_C(region_get_travel_cost, RID, p_region, rid_to_rid); + void FORWARD_2_C(region_set_map, RID, p_region, RID, p_map, rid_to_rid, rid_to_rid); void FORWARD_2_C(region_set_layers, RID, p_region, uint32_t, p_layers, rid_to_rid, uint32_to_uint32); uint32_t FORWARD_1_C(region_get_layers, RID, p_region, rid_to_rid); diff --git a/servers/navigation_server_2d.h b/servers/navigation_server_2d.h index dfdcf5fca853..8e285147b15e 100644 --- a/servers/navigation_server_2d.h +++ b/servers/navigation_server_2d.h @@ -86,6 +86,14 @@ class NavigationServer2D : public Object { /// Creates a new region. virtual RID region_create() const; + /// Set the enter_cost of a region + virtual void region_set_enter_cost(RID p_region, real_t p_enter_cost) const; + virtual real_t region_get_enter_cost(RID p_region) const; + + /// Set the travel_cost of a region + virtual void region_set_travel_cost(RID p_region, real_t p_travel_cost) const; + virtual real_t region_get_travel_cost(RID p_region) const; + /// Set the map of this region. virtual void region_set_map(RID p_region, RID p_map) const; virtual RID region_get_map(RID p_region) const; diff --git a/servers/navigation_server_3d.cpp b/servers/navigation_server_3d.cpp index 0ce869ad1ab8..6d99f6dfbb37 100644 --- a/servers/navigation_server_3d.cpp +++ b/servers/navigation_server_3d.cpp @@ -52,6 +52,10 @@ void NavigationServer3D::_bind_methods() { ClassDB::bind_method(D_METHOD("map_get_agents", "map"), &NavigationServer3D::map_get_agents); ClassDB::bind_method(D_METHOD("region_create"), &NavigationServer3D::region_create); + ClassDB::bind_method(D_METHOD("region_set_enter_cost", "region", "enter_cost"), &NavigationServer3D::region_set_enter_cost); + ClassDB::bind_method(D_METHOD("region_get_enter_cost", "region"), &NavigationServer3D::region_get_enter_cost); + ClassDB::bind_method(D_METHOD("region_set_travel_cost", "region", "travel_cost"), &NavigationServer3D::region_set_travel_cost); + ClassDB::bind_method(D_METHOD("region_get_travel_cost", "region"), &NavigationServer3D::region_get_travel_cost); ClassDB::bind_method(D_METHOD("region_set_map", "region", "map"), &NavigationServer3D::region_set_map); ClassDB::bind_method(D_METHOD("region_get_map", "region"), &NavigationServer3D::region_get_map); ClassDB::bind_method(D_METHOD("region_set_layers", "region", "layers"), &NavigationServer3D::region_set_layers); diff --git a/servers/navigation_server_3d.h b/servers/navigation_server_3d.h index c3d3a589a9f6..9b7e48e8d1cf 100644 --- a/servers/navigation_server_3d.h +++ b/servers/navigation_server_3d.h @@ -97,6 +97,14 @@ class NavigationServer3D : public Object { /// Creates a new region. virtual RID region_create() const = 0; + /// Set the enter_cost of a region + virtual void region_set_enter_cost(RID p_region, real_t p_enter_cost) const = 0; + virtual real_t region_get_enter_cost(RID p_region) const = 0; + + /// Set the travel_cost of a region + virtual void region_set_travel_cost(RID p_region, real_t p_travel_cost) const = 0; + virtual real_t region_get_travel_cost(RID p_region) const = 0; + /// Set the map of this region. virtual void region_set_map(RID p_region, RID p_map) const = 0; virtual RID region_get_map(RID p_region) const = 0;