diff --git a/doc/classes/CharacterBody2D.xml b/doc/classes/CharacterBody2D.xml index b66a01a282cb..fab9e1c66adf 100644 --- a/doc/classes/CharacterBody2D.xml +++ b/doc/classes/CharacterBody2D.xml @@ -135,12 +135,15 @@ + Moves the body based on [member velocity]. If the body collides with another, it will slide along the other body (by default only on floor) rather than stop immediately. If the other body is a [CharacterBody2D] or [RigidBody2D], it will also be affected by the motion of the other body. You can use this to make moving and rotating platforms, or to make nodes push other nodes. Modifies [member velocity] if a slide collision occurred. To get the latest collision call [method get_last_slide_collision], for detailed information about collisions that occurred, use [method get_slide_collision]. When the body touches a moving platform, the platform's velocity is automatically added to the body motion. If a collision occurs due to the platform's motion, it will always be first in the slide collisions. The general behavior and available properties change according to the [member motion_mode]. Returns [code]true[/code] if the body collided, otherwise, returns [code]false[/code]. + By default, the time delta used for motion depends on the context the method is called from. When called from [method Node._physics_process], the delta is the time passed between the current and last [i]physics[/i] frame. When called from [method Node._process], the delta is the time passed between the current and last [i]render[/i] frame. This can be overridden by passing a custom [param delta] value to the method. + [b]Note:[/b] [param delta] must be a positive number. Zero or negative values will be ignored. diff --git a/doc/classes/CharacterBody3D.xml b/doc/classes/CharacterBody3D.xml index 2382c77a12cc..69452cc33154 100644 --- a/doc/classes/CharacterBody3D.xml +++ b/doc/classes/CharacterBody3D.xml @@ -127,11 +127,14 @@ + Moves the body based on [member velocity]. If the body collides with another, it will slide along the other body rather than stop immediately. If the other body is a [CharacterBody3D] or [RigidBody3D], it will also be affected by the motion of the other body. You can use this to make moving and rotating platforms, or to make nodes push other nodes. Modifies [member velocity] if a slide collision occurred. To get the latest collision call [method get_last_slide_collision], for more detailed information about collisions that occurred, use [method get_slide_collision]. When the body touches a moving platform, the platform's velocity is automatically added to the body motion. If a collision occurs due to the platform's motion, it will always be first in the slide collisions. Returns [code]true[/code] if the body collided, otherwise, returns [code]false[/code]. + By default, the time delta used for motion depends on the context the method is called from. When called from [method Node._physics_process], the delta is the time passed between the current and last [i]physics[/i] frame. When called from [method Node._process], the delta is the time passed between the current and last [i]render[/i] frame. This can be overridden by passing a custom [param delta] value to the method. + [b]Note:[/b] [param delta] must be a positive number. Zero or negative values will treated as if no value was passed. diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp index 6af5a8dd8090..f1b62a3eb8e8 100644 --- a/scene/2d/physics_body_2d.cpp +++ b/scene/2d/physics_body_2d.cpp @@ -1106,9 +1106,12 @@ void RigidBody2D::_reload_physics_characteristics() { // So, if you pass 45 as limit, avoid numerical precision errors when angle is 45. #define FLOOR_ANGLE_THRESHOLD 0.01 -bool CharacterBody2D::move_and_slide() { - // Hack in order to work with calling from _process as well as from _physics_process; calling from thread is risky. - double delta = Engine::get_singleton()->is_in_physics_frame() ? get_physics_process_delta_time() : get_process_delta_time(); +bool CharacterBody2D::move_and_slide(double delta) { + // Non-positive delta value means nothing was passed (default is -1) or an invalid value, so we infer it from context + if (!(delta > 0)) { + // Hack in order to work with calling from _process as well as from _physics_process; calling from thread is risky. + delta = Engine::get_singleton()->is_in_physics_frame() ? get_physics_process_delta_time() : get_process_delta_time(); + } Vector2 current_platform_velocity = platform_velocity; Transform2D gt = get_global_transform(); @@ -1719,7 +1722,7 @@ void CharacterBody2D::_notification(int p_what) { } void CharacterBody2D::_bind_methods() { - ClassDB::bind_method(D_METHOD("move_and_slide"), &CharacterBody2D::move_and_slide); + ClassDB::bind_method(D_METHOD("move_and_slide", "delta"), &CharacterBody2D::move_and_slide, DEFVAL(-1.0)); ClassDB::bind_method(D_METHOD("apply_floor_snap"), &CharacterBody2D::apply_floor_snap); ClassDB::bind_method(D_METHOD("set_velocity", "velocity"), &CharacterBody2D::set_velocity); diff --git a/scene/2d/physics_body_2d.h b/scene/2d/physics_body_2d.h index f5448ead4082..d457aa6163a0 100644 --- a/scene/2d/physics_body_2d.h +++ b/scene/2d/physics_body_2d.h @@ -338,7 +338,7 @@ class CharacterBody2D : public PhysicsBody2D { PLATFORM_ON_LEAVE_ADD_UPWARD_VELOCITY, PLATFORM_ON_LEAVE_DO_NOTHING, }; - bool move_and_slide(); + bool move_and_slide(double delta = -1); void apply_floor_snap(); const Vector2 &get_velocity() const; diff --git a/scene/3d/physics_body_3d.cpp b/scene/3d/physics_body_3d.cpp index ed64c1656400..e200a9d74a62 100644 --- a/scene/3d/physics_body_3d.cpp +++ b/scene/3d/physics_body_3d.cpp @@ -1170,9 +1170,12 @@ void RigidBody3D::_reload_physics_characteristics() { //so, if you pass 45 as limit, avoid numerical precision errors when angle is 45. #define FLOOR_ANGLE_THRESHOLD 0.01 -bool CharacterBody3D::move_and_slide() { - // Hack in order to work with calling from _process as well as from _physics_process; calling from thread is risky - double delta = Engine::get_singleton()->is_in_physics_frame() ? get_physics_process_delta_time() : get_process_delta_time(); +bool CharacterBody3D::move_and_slide(double delta) { + // Non-positive delta value means nothing was passed (default is -1) or an invalid value, so we infer it from context + if (!(delta > 0)) { + // Hack in order to work with calling from _process as well as from _physics_process; calling from thread is risky. + delta = Engine::get_singleton()->is_in_physics_frame() ? get_physics_process_delta_time() : get_process_delta_time(); + } for (int i = 0; i < 3; i++) { if (locked_axis & (1 << i)) { @@ -1970,7 +1973,7 @@ void CharacterBody3D::_notification(int p_what) { } void CharacterBody3D::_bind_methods() { - ClassDB::bind_method(D_METHOD("move_and_slide"), &CharacterBody3D::move_and_slide); + ClassDB::bind_method(D_METHOD("move_and_slide", "delta"), &CharacterBody3D::move_and_slide, DEFVAL(-1.0)); ClassDB::bind_method(D_METHOD("apply_floor_snap"), &CharacterBody3D::apply_floor_snap); ClassDB::bind_method(D_METHOD("set_velocity", "velocity"), &CharacterBody3D::set_velocity); diff --git a/scene/3d/physics_body_3d.h b/scene/3d/physics_body_3d.h index 9798fc48450c..9894cc646c16 100644 --- a/scene/3d/physics_body_3d.h +++ b/scene/3d/physics_body_3d.h @@ -355,7 +355,7 @@ class CharacterBody3D : public PhysicsBody3D { PLATFORM_ON_LEAVE_ADD_UPWARD_VELOCITY, PLATFORM_ON_LEAVE_DO_NOTHING, }; - bool move_and_slide(); + bool move_and_slide(double delta = -1); void apply_floor_snap(); const Vector3 &get_velocity() const;