diff --git a/doc/classes/NavigationRegion2D.xml b/doc/classes/NavigationRegion2D.xml
index 89f7dcb4af0..0f280812013 100644
--- a/doc/classes/NavigationRegion2D.xml
+++ b/doc/classes/NavigationRegion2D.xml
@@ -10,6 +10,7 @@
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.
+ [b]Note:[/b] This node caches changes to its properties, so if you make changes to the underlying region [RID] in [NavigationServer2D], they will not be reflected in this node's properties.
diff --git a/doc/classes/NavigationRegion3D.xml b/doc/classes/NavigationRegion3D.xml
index 87e82e7b2eb..85f163b3c29 100644
--- a/doc/classes/NavigationRegion3D.xml
+++ b/doc/classes/NavigationRegion3D.xml
@@ -10,6 +10,7 @@
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.
+ [b]Note:[/b] This node caches changes to its properties, so if you make changes to the underlying region [RID] in [NavigationServer3D], they will not be reflected in this node's properties.
diff --git a/scene/2d/navigation_region_2d.cpp b/scene/2d/navigation_region_2d.cpp
index b1e2875a8bd..6e8ecb13b1c 100644
--- a/scene/2d/navigation_region_2d.cpp
+++ b/scene/2d/navigation_region_2d.cpp
@@ -354,10 +354,13 @@ void NavigationPolygon::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "outlines", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL), "_set_outlines", "_get_outlines");
}
+/////////////////////////////
+
void NavigationRegion2D::set_enabled(bool p_enabled) {
if (enabled == p_enabled) {
return;
}
+
enabled = p_enabled;
if (!is_inside_tree()) {
@@ -384,35 +387,50 @@ bool NavigationRegion2D::is_enabled() const {
}
void NavigationRegion2D::set_navigation_layers(uint32_t p_navigation_layers) {
- NavigationServer2D::get_singleton()->region_set_navigation_layers(region, p_navigation_layers);
+ if (navigation_layers == p_navigation_layers) {
+ return;
+ }
+
+ navigation_layers = p_navigation_layers;
+
+ NavigationServer2D::get_singleton()->region_set_navigation_layers(region, navigation_layers);
}
uint32_t NavigationRegion2D::get_navigation_layers() const {
- return NavigationServer2D::get_singleton()->region_get_navigation_layers(region);
+ return navigation_layers;
}
void NavigationRegion2D::set_navigation_layer_value(int p_layer_number, bool p_value) {
ERR_FAIL_COND_MSG(p_layer_number < 1, "Navigation layer number must be between 1 and 32 inclusive.");
ERR_FAIL_COND_MSG(p_layer_number > 32, "Navigation layer number must be between 1 and 32 inclusive.");
+
uint32_t _navigation_layers = get_navigation_layers();
+
if (p_value) {
_navigation_layers |= 1 << (p_layer_number - 1);
} else {
_navigation_layers &= ~(1 << (p_layer_number - 1));
}
+
set_navigation_layers(_navigation_layers);
}
bool NavigationRegion2D::get_navigation_layer_value(int p_layer_number) const {
ERR_FAIL_COND_V_MSG(p_layer_number < 1, false, "Navigation layer number must be between 1 and 32 inclusive.");
ERR_FAIL_COND_V_MSG(p_layer_number > 32, false, "Navigation layer number must be between 1 and 32 inclusive.");
+
return get_navigation_layers() & (1 << (p_layer_number - 1));
}
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);
+ if (Math::is_equal_approx(enter_cost, p_enter_cost)) {
+ return;
+ }
+
+ enter_cost = p_enter_cost;
+
+ NavigationServer2D::get_singleton()->region_set_enter_cost(region, enter_cost);
}
real_t NavigationRegion2D::get_enter_cost() const {
@@ -421,7 +439,12 @@ real_t NavigationRegion2D::get_enter_cost() const {
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);
+ if (Math::is_equal_approx(travel_cost, p_travel_cost)) {
+ return;
+ }
+
+ travel_cost = p_travel_cost;
+
NavigationServer2D::get_singleton()->region_set_travel_cost(region, travel_cost);
}
@@ -433,7 +456,6 @@ RID NavigationRegion2D::get_region_rid() const {
return region;
}
-/////////////////////////////
#ifdef TOOLS_ENABLED
Rect2 NavigationRegion2D::_edit_get_rect() const {
return navpoly.is_valid() ? navpoly->_edit_get_rect() : Rect2();
diff --git a/scene/2d/navigation_region_2d.h b/scene/2d/navigation_region_2d.h
index 893de41a94b..c630e20780d 100644
--- a/scene/2d/navigation_region_2d.h
+++ b/scene/2d/navigation_region_2d.h
@@ -96,10 +96,10 @@ class NavigationRegion2D : public Node2D {
bool enabled = true;
RID region;
- Ref navpoly;
-
+ uint32_t navigation_layers = 1;
real_t enter_cost = 0.0;
real_t travel_cost = 1.0;
+ Ref navpoly;
void _navpoly_changed();
void _map_changed(RID p_RID);
diff --git a/scene/3d/navigation_region_3d.cpp b/scene/3d/navigation_region_3d.cpp
index bfc43531381..b060d314bac 100644
--- a/scene/3d/navigation_region_3d.cpp
+++ b/scene/3d/navigation_region_3d.cpp
@@ -37,6 +37,7 @@ void NavigationRegion3D::set_enabled(bool p_enabled) {
if (enabled == p_enabled) {
return;
}
+
enabled = p_enabled;
if (!is_inside_tree()) {
@@ -81,35 +82,50 @@ bool NavigationRegion3D::is_enabled() const {
}
void NavigationRegion3D::set_navigation_layers(uint32_t p_navigation_layers) {
- NavigationServer3D::get_singleton()->region_set_navigation_layers(region, p_navigation_layers);
+ if (navigation_layers == p_navigation_layers) {
+ return;
+ }
+
+ navigation_layers = p_navigation_layers;
+
+ NavigationServer3D::get_singleton()->region_set_navigation_layers(region, navigation_layers);
}
uint32_t NavigationRegion3D::get_navigation_layers() const {
- return NavigationServer3D::get_singleton()->region_get_navigation_layers(region);
+ return navigation_layers;
}
void NavigationRegion3D::set_navigation_layer_value(int p_layer_number, bool p_value) {
ERR_FAIL_COND_MSG(p_layer_number < 1, "Navigation layer number must be between 1 and 32 inclusive.");
ERR_FAIL_COND_MSG(p_layer_number > 32, "Navigation layer number must be between 1 and 32 inclusive.");
+
uint32_t _navigation_layers = get_navigation_layers();
+
if (p_value) {
_navigation_layers |= 1 << (p_layer_number - 1);
} else {
_navigation_layers &= ~(1 << (p_layer_number - 1));
}
+
set_navigation_layers(_navigation_layers);
}
bool NavigationRegion3D::get_navigation_layer_value(int p_layer_number) const {
ERR_FAIL_COND_V_MSG(p_layer_number < 1, false, "Navigation layer number must be between 1 and 32 inclusive.");
ERR_FAIL_COND_V_MSG(p_layer_number > 32, false, "Navigation layer number must be between 1 and 32 inclusive.");
+
return get_navigation_layers() & (1 << (p_layer_number - 1));
}
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);
+ if (Math::is_equal_approx(enter_cost, p_enter_cost)) {
+ return;
+ }
+
+ enter_cost = p_enter_cost;
+
+ NavigationServer3D::get_singleton()->region_set_enter_cost(region, enter_cost);
}
real_t NavigationRegion3D::get_enter_cost() const {
@@ -118,7 +134,12 @@ real_t NavigationRegion3D::get_enter_cost() const {
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);
+ if (Math::is_equal_approx(travel_cost, p_travel_cost)) {
+ return;
+ }
+
+ travel_cost = p_travel_cost;
+
NavigationServer3D::get_singleton()->region_set_travel_cost(region, travel_cost);
}
@@ -130,8 +151,6 @@ RID NavigationRegion3D::get_region_rid() const {
return region;
}
-/////////////////////////////
-
void NavigationRegion3D::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE: {
diff --git a/scene/3d/navigation_region_3d.h b/scene/3d/navigation_region_3d.h
index 7d16d81d77a..660538d314c 100644
--- a/scene/3d/navigation_region_3d.h
+++ b/scene/3d/navigation_region_3d.h
@@ -39,10 +39,10 @@ class NavigationRegion3D : public Node3D {
bool enabled = true;
RID region;
- Ref navmesh;
-
+ uint32_t navigation_layers = 1;
real_t enter_cost = 0.0;
real_t travel_cost = 1.0;
+ Ref navmesh;
Thread bake_thread;