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;