summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/classes/PhysicsBody2D.xml6
-rw-r--r--doc/classes/PhysicsBody3D.xml6
-rw-r--r--scene/2d/physics_body_2d.cpp12
-rw-r--r--scene/3d/physics_body_3d.cpp12
4 files changed, 28 insertions, 8 deletions
diff --git a/doc/classes/PhysicsBody2D.xml b/doc/classes/PhysicsBody2D.xml
index e108ab6298..7775cfb2f9 100644
--- a/doc/classes/PhysicsBody2D.xml
+++ b/doc/classes/PhysicsBody2D.xml
@@ -30,7 +30,7 @@
<argument index="2" name="safe_margin" type="float" default="0.08" />
<description>
Moves the body along the vector [code]linear_velocity[/code]. This method should be used in [method Node._physics_process] (or in a method called by [method Node._physics_process]), as it uses the physics step's [code]delta[/code] value automatically in calculations. Otherwise, the simulation will run at an incorrect speed.
- The body will stop if it collides. Returns a [KinematicCollision2D], which contains information about the collision.
+ The body will stop if it collides. Returns a [KinematicCollision2D], which contains information about the collision when stopped, or when touching another body along the motion.
If [code]test_only[/code] is [code]true[/code], the body does not move but the would-be collision information is given.
[code]safe_margin[/code] is the extra margin used for collision recovery (see [member CharacterBody2D.collision/safe_margin] for more details).
</description>
@@ -50,8 +50,8 @@
<argument index="3" name="safe_margin" type="float" default="0.08" />
<description>
Checks for collisions without moving the body. This method should be used in [method Node._physics_process] (or in a method called by [method Node._physics_process]), as it uses the physics step's [code]delta[/code] value automatically in calculations. Otherwise, the simulation will run at an incorrect speed.
- Virtually sets the node's position, scale and rotation to that of the given [Transform2D], then tries to move the body along the vector [code]linear_velocity[/code]. Returns [code]true[/code] if a collision would occur.
- [code]collision[/code] is an optional object of type [KinematicCollision2D], which contains additional information about the collision (should there be one).
+ Virtually sets the node's position, scale and rotation to that of the given [Transform2D], then tries to move the body along the vector [code]linear_velocity[/code]. Returns [code]true[/code] if a collision would stop the body from moving along the whole path.
+ [code]collision[/code] is an optional object of type [KinematicCollision2D], which contains additional information about the collision when stopped, or when touching another body along the motion.
[code]safe_margin[/code] is the extra margin used for collision recovery (see [member CharacterBody2D.collision/safe_margin] for more details).
</description>
</method>
diff --git a/doc/classes/PhysicsBody3D.xml b/doc/classes/PhysicsBody3D.xml
index 8718c0caa2..9cf587f2e0 100644
--- a/doc/classes/PhysicsBody3D.xml
+++ b/doc/classes/PhysicsBody3D.xml
@@ -38,7 +38,7 @@
<argument index="3" name="max_collisions" type="int" default="1" />
<description>
Moves the body along the vector [code]linear_velocity[/code]. This method should be used in [method Node._physics_process] (or in a method called by [method Node._physics_process]), as it uses the physics step's [code]delta[/code] value automatically in calculations. Otherwise, the simulation will run at an incorrect speed.
- The body will stop if it collides. Returns a [KinematicCollision3D], which contains information about the collision.
+ The body will stop if it collides. Returns a [KinematicCollision3D], which contains information about the collision when stopped, or when touching another body along the motion.
If [code]test_only[/code] is [code]true[/code], the body does not move but the would-be collision information is given.
[code]safe_margin[/code] is the extra margin used for collision recovery (see [member CharacterBody3D.collision/safe_margin] for more details).
[code]max_collisions[/code] allows to retrieve more than one collision result.
@@ -68,8 +68,8 @@
<argument index="4" name="max_collisions" type="int" default="1" />
<description>
Checks for collisions without moving the body. This method should be used in [method Node._physics_process] (or in a method called by [method Node._physics_process]), as it uses the physics step's [code]delta[/code] value automatically in calculations. Otherwise, the simulation will run at an incorrect speed.
- Virtually sets the node's position, scale and rotation to that of the given [Transform3D], then tries to move the body along the vector [code]linear_velocity[/code]. Returns [code]true[/code] if a collision would occur.
- [code]collision[/code] is an optional object of type [KinematicCollision3D], which contains additional information about the collision (should there be one).
+ Virtually sets the node's position, scale and rotation to that of the given [Transform3D], then tries to move the body along the vector [code]linear_velocity[/code]. Returns [code]true[/code] if a collision would stop the body from moving along the whole path.
+ [code]collision[/code] is an optional object of type [KinematicCollision3D], which contains additional information about the collision when stopped, or when touching another body along the motion.
[code]safe_margin[/code] is the extra margin used for collision recovery (see [member CharacterBody3D.collision/safe_margin] for more details).
[code]max_collisions[/code] allows to retrieve more than one collision result.
</description>
diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp
index 9d140f744f..5ec2a81108 100644
--- a/scene/2d/physics_body_2d.cpp
+++ b/scene/2d/physics_body_2d.cpp
@@ -133,9 +133,12 @@ bool PhysicsBody2D::test_move(const Transform2D &p_from, const Vector2 &p_linear
ERR_FAIL_COND_V(!is_inside_tree(), false);
PhysicsServer2D::MotionResult *r = nullptr;
+ PhysicsServer2D::MotionResult temp_result;
if (r_collision.is_valid()) {
// Needs const_cast because method bindings don't support non-const Ref.
r = const_cast<PhysicsServer2D::MotionResult *>(&r_collision->result);
+ } else {
+ r = &temp_result;
}
// Hack in order to work with calling from _process as well as from _physics_process; calling from thread is risky.
@@ -143,7 +146,14 @@ bool PhysicsBody2D::test_move(const Transform2D &p_from, const Vector2 &p_linear
PhysicsServer2D::MotionParameters parameters(p_from, p_linear_velocity * delta, p_margin);
- return PhysicsServer2D::get_singleton()->body_test_motion(get_rid(), parameters, r);
+ bool colliding = PhysicsServer2D::get_singleton()->body_test_motion(get_rid(), parameters, r);
+
+ if (colliding) {
+ // Don't report collision when the whole motion is done.
+ return (r->collision_safe_fraction < 1.0);
+ } else {
+ return false;
+ }
}
TypedArray<PhysicsBody2D> PhysicsBody2D::get_collision_exceptions() {
diff --git a/scene/3d/physics_body_3d.cpp b/scene/3d/physics_body_3d.cpp
index ea881b6d54..5cb7f431e3 100644
--- a/scene/3d/physics_body_3d.cpp
+++ b/scene/3d/physics_body_3d.cpp
@@ -174,9 +174,12 @@ bool PhysicsBody3D::test_move(const Transform3D &p_from, const Vector3 &p_linear
ERR_FAIL_COND_V(!is_inside_tree(), false);
PhysicsServer3D::MotionResult *r = nullptr;
+ PhysicsServer3D::MotionResult temp_result;
if (r_collision.is_valid()) {
// Needs const_cast because method bindings don't support non-const Ref.
r = const_cast<PhysicsServer3D::MotionResult *>(&r_collision->result);
+ } else {
+ r = &temp_result;
}
// Hack in order to work with calling from _process as well as from _physics_process; calling from thread is risky
@@ -184,7 +187,14 @@ bool PhysicsBody3D::test_move(const Transform3D &p_from, const Vector3 &p_linear
PhysicsServer3D::MotionParameters parameters(p_from, p_linear_velocity * delta, p_margin);
- return PhysicsServer3D::get_singleton()->body_test_motion(get_rid(), parameters, r);
+ bool colliding = PhysicsServer3D::get_singleton()->body_test_motion(get_rid(), parameters, r);
+
+ if (colliding) {
+ // Don't report collision when the whole motion is done.
+ return (r->collision_safe_fraction < 1.0);
+ } else {
+ return false;
+ }
}
void PhysicsBody3D::set_axis_lock(PhysicsServer3D::BodyAxis p_axis, bool p_lock) {