Fix test_move reporting collision when touching another body
Reporting rest collision information is needed for move_and_collide and move_and_slide so floor detection can be done properly, but in the case of just testing the motion for collision, it makes sense to return false if the body is able to move all along the path without being stopped. Updated the logic in test_move and clarified the documentation for test_move and move_and_collide.
This commit is contained in:
parent
3401ef1ccb
commit
1560c8b5aa
|
@ -86,7 +86,7 @@
|
|||
<argument index="2" name="exclude_raycast_shapes" type="bool" default="true" />
|
||||
<argument index="3" name="test_only" type="bool" default="false" />
|
||||
<description>
|
||||
Moves the body along the vector [code]rel_vec[/code]. The body will stop if it collides. Returns a [KinematicCollision], which contains information about the collision.
|
||||
Moves the body along the vector [code]rel_vec[/code]. The body will stop if it collides. Returns a [KinematicCollision], 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.
|
||||
</description>
|
||||
</method>
|
||||
|
@ -139,7 +139,8 @@
|
|||
<argument index="1" name="rel_vec" type="Vector3" />
|
||||
<argument index="2" name="infinite_inertia" type="bool" default="true" />
|
||||
<description>
|
||||
Checks for collisions without moving the body. Virtually sets the node's position, scale and rotation to that of the given [Transform], then tries to move the body along the vector [code]rel_vec[/code]. Returns [code]true[/code] if a collision would occur.
|
||||
Checks for collisions without moving the body. Virtually sets the node's position, scale and rotation to that of the given [Transform], then tries to move the body along the vector [code]rel_vec[/code]. Returns [code]true[/code] if a collision would stop the body from moving along the whole path.
|
||||
Use [method move_and_collide] instead for detecting collision with touching bodies.
|
||||
</description>
|
||||
</method>
|
||||
</methods>
|
||||
|
|
|
@ -84,7 +84,7 @@
|
|||
<argument index="2" name="exclude_raycast_shapes" type="bool" default="true" />
|
||||
<argument index="3" name="test_only" type="bool" default="false" />
|
||||
<description>
|
||||
Moves the body along the vector [code]rel_vec[/code]. The body will stop if it collides. Returns a [KinematicCollision2D], which contains information about the collision.
|
||||
Moves the body along the vector [code]rel_vec[/code]. 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.
|
||||
</description>
|
||||
</method>
|
||||
|
@ -129,7 +129,8 @@
|
|||
<argument index="1" name="rel_vec" type="Vector2" />
|
||||
<argument index="2" name="infinite_inertia" type="bool" default="true" />
|
||||
<description>
|
||||
Checks for collisions without moving the body. 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]rel_vec[/code]. Returns [code]true[/code] if a collision would occur.
|
||||
Checks for collisions without moving the body. 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]rel_vec[/code]. Returns [code]true[/code] if a collision would stop the body from moving along the whole path.
|
||||
Use [method move_and_collide] instead for detecting collision with touching bodies.
|
||||
</description>
|
||||
</method>
|
||||
</methods>
|
||||
|
|
|
@ -345,10 +345,21 @@ struct _RigidBody2DInOut {
|
|||
|
||||
bool RigidBody2D::_test_motion(const Vector2 &p_motion, bool p_infinite_inertia, float p_margin, const Ref<Physics2DTestMotionResult> &p_result) {
|
||||
Physics2DServer::MotionResult *r = nullptr;
|
||||
Physics2DServer::MotionResult temp_result;
|
||||
if (p_result.is_valid()) {
|
||||
r = p_result->get_result_ptr();
|
||||
} else {
|
||||
r = &temp_result;
|
||||
}
|
||||
|
||||
bool colliding = Physics2DServer::get_singleton()->body_test_motion(get_rid(), get_global_transform(), p_motion, p_infinite_inertia, p_margin, r);
|
||||
|
||||
if (colliding) {
|
||||
// Don't report collision when the whole motion is done.
|
||||
return (r->collision_safe_fraction < 1.0);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return Physics2DServer::get_singleton()->body_test_motion(get_rid(), get_global_transform(), p_motion, p_infinite_inertia, p_margin, r);
|
||||
}
|
||||
|
||||
void RigidBody2D::_direct_state_changed(Object *p_state) {
|
||||
|
@ -1299,7 +1310,15 @@ Vector2 KinematicBody2D::get_floor_velocity() const {
|
|||
bool KinematicBody2D::test_move(const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia) {
|
||||
ERR_FAIL_COND_V(!is_inside_tree(), false);
|
||||
|
||||
return Physics2DServer::get_singleton()->body_test_motion(get_rid(), p_from, p_motion, p_infinite_inertia, margin);
|
||||
Physics2DServer::MotionResult result;
|
||||
bool colliding = Physics2DServer::get_singleton()->body_test_motion(get_rid(), p_from, p_motion, p_infinite_inertia, margin, &result);
|
||||
|
||||
if (colliding) {
|
||||
// Don't report collision when the whole motion is done.
|
||||
return (result.collision_safe_fraction < 1.0);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void KinematicBody2D::set_safe_margin(float p_margin) {
|
||||
|
|
|
@ -1259,7 +1259,15 @@ Vector3 KinematicBody::get_floor_velocity() const {
|
|||
bool KinematicBody::test_move(const Transform &p_from, const Vector3 &p_motion, bool p_infinite_inertia) {
|
||||
ERR_FAIL_COND_V(!is_inside_tree(), false);
|
||||
|
||||
return PhysicsServer::get_singleton()->body_test_motion(get_rid(), p_from, p_motion, p_infinite_inertia);
|
||||
PhysicsServer::MotionResult result;
|
||||
bool colliding = PhysicsServer::get_singleton()->body_test_motion(get_rid(), p_from, p_motion, p_infinite_inertia, &result);
|
||||
|
||||
if (colliding) {
|
||||
// Don't report collision when the whole motion is done.
|
||||
return (result.collision_safe_fraction < 1.0);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool KinematicBody::separate_raycast_shapes(bool p_infinite_inertia, Collision &r_collision) {
|
||||
|
|
Loading…
Reference in New Issue