Merge pull request #83705 from smix8/agent_y_velocity_.4x
Fix NavigationAgent3D stored y-axis velocity and make it optional
This commit is contained in:
commit
d2cd907e28
3 changed files with 34 additions and 1 deletions
|
@ -167,6 +167,9 @@
|
|||
<member name="height" type="float" setter="set_height" getter="get_height" default="1.0">
|
||||
The height of the avoidance agent. Agents will ignore other agents or obstacles that are above or below their current position + height in 2D avoidance. Does nothing in 3D avoidance which uses radius spheres alone.
|
||||
</member>
|
||||
<member name="keep_y_velocity" type="bool" setter="set_keep_y_velocity" getter="get_keep_y_velocity" default="true">
|
||||
If [code]true[/code] and the agent uses 2D avoidance it will remember the set y-axis velocity and reapply it after the avoidance step. While 2D avoidance has no y-axis and simulates on a flat plane this setting can help mitigate the most obvious clipping on uneven 3D geometry.
|
||||
</member>
|
||||
<member name="max_neighbors" type="int" setter="set_max_neighbors" getter="get_max_neighbors" default="10">
|
||||
The maximum number of neighbors for the agent to consider.
|
||||
</member>
|
||||
|
|
|
@ -57,6 +57,9 @@ void NavigationAgent3D::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("set_use_3d_avoidance", "enabled"), &NavigationAgent3D::set_use_3d_avoidance);
|
||||
ClassDB::bind_method(D_METHOD("get_use_3d_avoidance"), &NavigationAgent3D::get_use_3d_avoidance);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_keep_y_velocity", "enabled"), &NavigationAgent3D::set_keep_y_velocity);
|
||||
ClassDB::bind_method(D_METHOD("get_keep_y_velocity"), &NavigationAgent3D::get_keep_y_velocity);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_neighbor_distance", "neighbor_distance"), &NavigationAgent3D::set_neighbor_distance);
|
||||
ClassDB::bind_method(D_METHOD("get_neighbor_distance"), &NavigationAgent3D::get_neighbor_distance);
|
||||
|
||||
|
@ -149,6 +152,7 @@ void NavigationAgent3D::_bind_methods() {
|
|||
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "time_horizon_obstacles", PROPERTY_HINT_RANGE, "0.0,10,0.01,or_greater,suffix:s"), "set_time_horizon_obstacles", "get_time_horizon_obstacles");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "max_speed", PROPERTY_HINT_RANGE, "0.01,10000,0.01,or_greater,suffix:m/s"), "set_max_speed", "get_max_speed");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_3d_avoidance"), "set_use_3d_avoidance", "get_use_3d_avoidance");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "keep_y_velocity"), "set_keep_y_velocity", "get_keep_y_velocity");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "avoidance_layers", PROPERTY_HINT_LAYERS_AVOIDANCE), "set_avoidance_layers", "get_avoidance_layers");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "avoidance_mask", PROPERTY_HINT_LAYERS_AVOIDANCE), "set_avoidance_mask", "get_avoidance_mask");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "avoidance_priority", PROPERTY_HINT_RANGE, "0.0,1.0,0.01"), "set_avoidance_priority", "get_avoidance_priority");
|
||||
|
@ -281,7 +285,9 @@ void NavigationAgent3D::_notification(int p_what) {
|
|||
velocity_submitted = false;
|
||||
if (avoidance_enabled) {
|
||||
if (!use_3d_avoidance) {
|
||||
if (keep_y_velocity) {
|
||||
stored_y_velocity = velocity.y;
|
||||
}
|
||||
velocity.y = 0.0;
|
||||
}
|
||||
NavigationServer3D::get_singleton()->agent_set_velocity(agent, velocity);
|
||||
|
@ -304,6 +310,15 @@ void NavigationAgent3D::_notification(int p_what) {
|
|||
}
|
||||
}
|
||||
|
||||
void NavigationAgent3D::_validate_property(PropertyInfo &p_property) const {
|
||||
if (p_property.name == "keep_y_velocity") {
|
||||
if (use_3d_avoidance) {
|
||||
p_property.usage = PROPERTY_USAGE_NONE;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NavigationAgent3D::NavigationAgent3D() {
|
||||
agent = NavigationServer3D::get_singleton()->agent_create();
|
||||
|
||||
|
@ -523,6 +538,15 @@ void NavigationAgent3D::set_use_3d_avoidance(bool p_use_3d_avoidance) {
|
|||
notify_property_list_changed();
|
||||
}
|
||||
|
||||
void NavigationAgent3D::set_keep_y_velocity(bool p_enabled) {
|
||||
keep_y_velocity = p_enabled;
|
||||
stored_y_velocity = 0.0;
|
||||
}
|
||||
|
||||
bool NavigationAgent3D::get_keep_y_velocity() const {
|
||||
return keep_y_velocity;
|
||||
}
|
||||
|
||||
void NavigationAgent3D::set_neighbor_distance(real_t p_distance) {
|
||||
if (Math::is_equal_approx(neighbor_distance, p_distance)) {
|
||||
return;
|
||||
|
@ -807,6 +831,7 @@ void NavigationAgent3D::update_navigation() {
|
|||
NavigationServer3D::get_singleton()->agent_set_position(agent, agent_parent->get_global_transform().origin);
|
||||
NavigationServer3D::get_singleton()->agent_set_velocity(agent, Vector3(0.0, 0.0, 0.0));
|
||||
NavigationServer3D::get_singleton()->agent_set_velocity_forced(agent, Vector3(0.0, 0.0, 0.0));
|
||||
stored_y_velocity = 0.0;
|
||||
}
|
||||
emit_signal(SNAME("navigation_finished"));
|
||||
break;
|
||||
|
|
|
@ -89,6 +89,7 @@ class NavigationAgent3D : public Node {
|
|||
|
||||
// 2D avoidance has no y-axis. This stores and reapplies the y-axis velocity to the agent before and after the avoidance step.
|
||||
// While not perfect it at least looks way better than agent's that clip through everything that is not a flat surface
|
||||
bool keep_y_velocity = true;
|
||||
float stored_y_velocity = 0.0;
|
||||
|
||||
bool target_position_submitted = false;
|
||||
|
@ -114,6 +115,7 @@ class NavigationAgent3D : public Node {
|
|||
protected:
|
||||
static void _bind_methods();
|
||||
void _notification(int p_what);
|
||||
void _validate_property(PropertyInfo &p_property) const;
|
||||
|
||||
#ifndef DISABLE_DEPRECATED
|
||||
bool _set(const StringName &p_name, const Variant &p_value);
|
||||
|
@ -173,6 +175,9 @@ public:
|
|||
void set_use_3d_avoidance(bool p_use_3d_avoidance);
|
||||
bool get_use_3d_avoidance() const { return use_3d_avoidance; }
|
||||
|
||||
void set_keep_y_velocity(bool p_enabled);
|
||||
bool get_keep_y_velocity() const;
|
||||
|
||||
void set_neighbor_distance(real_t p_distance);
|
||||
real_t get_neighbor_distance() const { return neighbor_distance; }
|
||||
|
||||
|
|
Loading…
Reference in a new issue