summaryrefslogtreecommitdiff
path: root/scene/2d/navigation_agent_2d.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'scene/2d/navigation_agent_2d.cpp')
-rw-r--r--scene/2d/navigation_agent_2d.cpp79
1 files changed, 67 insertions, 12 deletions
diff --git a/scene/2d/navigation_agent_2d.cpp b/scene/2d/navigation_agent_2d.cpp
index 80d60dca17..5a451a6dab 100644
--- a/scene/2d/navigation_agent_2d.cpp
+++ b/scene/2d/navigation_agent_2d.cpp
@@ -40,6 +40,9 @@ void NavigationAgent2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_avoidance_enabled", "enabled"), &NavigationAgent2D::set_avoidance_enabled);
ClassDB::bind_method(D_METHOD("get_avoidance_enabled"), &NavigationAgent2D::get_avoidance_enabled);
+ ClassDB::bind_method(D_METHOD("set_path_desired_distance", "desired_distance"), &NavigationAgent2D::set_path_desired_distance);
+ ClassDB::bind_method(D_METHOD("get_path_desired_distance"), &NavigationAgent2D::get_path_desired_distance);
+
ClassDB::bind_method(D_METHOD("set_target_desired_distance", "desired_distance"), &NavigationAgent2D::set_target_desired_distance);
ClassDB::bind_method(D_METHOD("get_target_desired_distance"), &NavigationAgent2D::get_target_desired_distance);
@@ -61,8 +64,14 @@ void NavigationAgent2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_path_max_distance", "max_speed"), &NavigationAgent2D::set_path_max_distance);
ClassDB::bind_method(D_METHOD("get_path_max_distance"), &NavigationAgent2D::get_path_max_distance);
- ClassDB::bind_method(D_METHOD("set_navigable_layers", "navigable_layers"), &NavigationAgent2D::set_navigable_layers);
- ClassDB::bind_method(D_METHOD("get_navigable_layers"), &NavigationAgent2D::get_navigable_layers);
+ ClassDB::bind_method(D_METHOD("set_navigation_layers", "navigation_layers"), &NavigationAgent2D::set_navigation_layers);
+ ClassDB::bind_method(D_METHOD("get_navigation_layers"), &NavigationAgent2D::get_navigation_layers);
+
+ ClassDB::bind_method(D_METHOD("set_navigation_layer_value", "layer_number", "value"), &NavigationAgent2D::set_navigation_layer_value);
+ ClassDB::bind_method(D_METHOD("get_navigation_layer_value", "layer_number"), &NavigationAgent2D::get_navigation_layer_value);
+
+ ClassDB::bind_method(D_METHOD("set_navigation_map", "navigation_map"), &NavigationAgent2D::set_navigation_map);
+ ClassDB::bind_method(D_METHOD("get_navigation_map"), &NavigationAgent2D::get_navigation_map);
ClassDB::bind_method(D_METHOD("set_target_location", "location"), &NavigationAgent2D::set_target_location);
ClassDB::bind_method(D_METHOD("get_target_location"), &NavigationAgent2D::get_target_location);
@@ -78,6 +87,7 @@ void NavigationAgent2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("_avoidance_done", "new_velocity"), &NavigationAgent2D::_avoidance_done);
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "path_desired_distance", PROPERTY_HINT_RANGE, "0.1,100,0.01,suffix:px"), "set_path_desired_distance", "get_path_desired_distance");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "target_desired_distance", PROPERTY_HINT_RANGE, "0.1,100,0.01,suffix:px"), "set_target_desired_distance", "get_target_desired_distance");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "radius", PROPERTY_HINT_RANGE, "0.1,500,0.01,suffix:px"), "set_radius", "get_radius");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "neighbor_dist", PROPERTY_HINT_RANGE, "0.1,100000,0.01,suffix:px"), "set_neighbor_dist", "get_neighbor_dist");
@@ -86,7 +96,7 @@ void NavigationAgent2D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "max_speed", PROPERTY_HINT_RANGE, "0.1,100000,0.01,suffix:px/s"), "set_max_speed", "get_max_speed");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "path_max_distance", PROPERTY_HINT_RANGE, "10,100,1,suffix:px"), "set_path_max_distance", "get_path_max_distance");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "avoidance_enabled"), "set_avoidance_enabled", "get_avoidance_enabled");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "navigable_layers", PROPERTY_HINT_LAYERS_2D_NAVIGATION), "set_navigable_layers", "get_navigable_layers");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "navigation_layers", PROPERTY_HINT_LAYERS_2D_NAVIGATION), "set_navigation_layers", "get_navigation_layers");
ADD_SIGNAL(MethodInfo("path_changed"));
ADD_SIGNAL(MethodInfo("target_reached"));
@@ -191,7 +201,11 @@ void NavigationAgent2D::set_agent_parent(Node *p_agent_parent) {
if (Object::cast_to<Node2D>(p_agent_parent) != nullptr) {
// place agent on navigation map first or else the RVO agent callback creation fails silently later
agent_parent = Object::cast_to<Node2D>(p_agent_parent);
- NavigationServer2D::get_singleton()->agent_set_map(get_rid(), agent_parent->get_world_2d()->get_navigation_map());
+ if (map_override.is_valid()) {
+ NavigationServer2D::get_singleton()->agent_set_map(get_rid(), map_override);
+ } else {
+ NavigationServer2D::get_singleton()->agent_set_map(get_rid(), agent_parent->get_world_2d()->get_navigation_map());
+ }
// create new avoidance callback if enabled
set_avoidance_enabled(avoidance_enabled);
} else {
@@ -200,16 +214,53 @@ void NavigationAgent2D::set_agent_parent(Node *p_agent_parent) {
}
}
-void NavigationAgent2D::set_navigable_layers(uint32_t p_layers) {
- bool layers_changed = navigable_layers != p_layers;
- navigable_layers = p_layers;
- if (layers_changed) {
+void NavigationAgent2D::set_navigation_layers(uint32_t p_navigation_layers) {
+ bool navigation_layers_changed = navigation_layers != p_navigation_layers;
+ navigation_layers = p_navigation_layers;
+ if (navigation_layers_changed) {
_request_repath();
}
}
-uint32_t NavigationAgent2D::get_navigable_layers() const {
- return navigable_layers;
+uint32_t NavigationAgent2D::get_navigation_layers() const {
+ return navigation_layers;
+}
+
+void NavigationAgent2D::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 NavigationAgent2D::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 NavigationAgent2D::set_navigation_map(RID p_navigation_map) {
+ map_override = p_navigation_map;
+ NavigationServer2D::get_singleton()->agent_set_map(agent, map_override);
+ _request_repath();
+}
+
+RID NavigationAgent2D::get_navigation_map() const {
+ if (map_override.is_valid()) {
+ return map_override;
+ } else if (agent_parent != nullptr) {
+ return agent_parent->get_world_2d()->get_navigation_map();
+ }
+ return RID();
+}
+
+void NavigationAgent2D::set_path_desired_distance(real_t p_dd) {
+ path_desired_distance = p_dd;
}
void NavigationAgent2D::set_target_desired_distance(real_t p_dd) {
@@ -360,7 +411,11 @@ void NavigationAgent2D::update_navigation() {
}
if (reload_path) {
- navigation_path = NavigationServer2D::get_singleton()->map_get_path(agent_parent->get_world_2d()->get_navigation_map(), o, target_location, true, navigable_layers);
+ if (map_override.is_valid()) {
+ navigation_path = NavigationServer2D::get_singleton()->map_get_path(map_override, o, target_location, true, navigation_layers);
+ } else {
+ navigation_path = NavigationServer2D::get_singleton()->map_get_path(agent_parent->get_world_2d()->get_navigation_map(), o, target_location, true, navigation_layers);
+ }
navigation_finished = false;
nav_path_index = 0;
emit_signal(SNAME("path_changed"));
@@ -373,7 +428,7 @@ void NavigationAgent2D::update_navigation() {
// Check if we can advance the navigation path
if (navigation_finished == false) {
// Advances to the next far away location.
- while (o.distance_to(navigation_path[nav_path_index]) < target_desired_distance) {
+ while (o.distance_to(navigation_path[nav_path_index]) < path_desired_distance) {
nav_path_index += 1;
if (nav_path_index == navigation_path.size()) {
_check_distance_to_target();