diff options
Diffstat (limited to 'scene/2d/physics_body_2d.cpp')
-rw-r--r-- | scene/2d/physics_body_2d.cpp | 85 |
1 files changed, 66 insertions, 19 deletions
diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp index f493d97ceb..f0e51097db 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() { @@ -684,6 +694,24 @@ real_t RigidDynamicBody2D::get_gravity_scale() const { return gravity_scale; } +void RigidDynamicBody2D::set_linear_damp_mode(DampMode p_mode) { + linear_damp_mode = p_mode; + PhysicsServer2D::get_singleton()->body_set_param(get_rid(), PhysicsServer2D::BODY_PARAM_LINEAR_DAMP_MODE, linear_damp_mode); +} + +RigidDynamicBody2D::DampMode RigidDynamicBody2D::get_linear_damp_mode() const { + return linear_damp_mode; +} + +void RigidDynamicBody2D::set_angular_damp_mode(DampMode p_mode) { + angular_damp_mode = p_mode; + PhysicsServer2D::get_singleton()->body_set_param(get_rid(), PhysicsServer2D::BODY_PARAM_ANGULAR_DAMP_MODE, angular_damp_mode); +} + +RigidDynamicBody2D::DampMode RigidDynamicBody2D::get_angular_damp_mode() const { + return angular_damp_mode; +} + void RigidDynamicBody2D::set_linear_damp(real_t p_linear_damp) { ERR_FAIL_COND(p_linear_damp < -1); linear_damp = p_linear_damp; @@ -916,6 +944,12 @@ void RigidDynamicBody2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_gravity_scale", "gravity_scale"), &RigidDynamicBody2D::set_gravity_scale); ClassDB::bind_method(D_METHOD("get_gravity_scale"), &RigidDynamicBody2D::get_gravity_scale); + ClassDB::bind_method(D_METHOD("set_linear_damp_mode", "linear_damp_mode"), &RigidDynamicBody2D::set_linear_damp_mode); + ClassDB::bind_method(D_METHOD("get_linear_damp_mode"), &RigidDynamicBody2D::get_linear_damp_mode); + + ClassDB::bind_method(D_METHOD("set_angular_damp_mode", "angular_damp_mode"), &RigidDynamicBody2D::set_angular_damp_mode); + ClassDB::bind_method(D_METHOD("get_angular_damp_mode"), &RigidDynamicBody2D::get_angular_damp_mode); + ClassDB::bind_method(D_METHOD("set_linear_damp", "linear_damp"), &RigidDynamicBody2D::set_linear_damp); ClassDB::bind_method(D_METHOD("get_linear_damp"), &RigidDynamicBody2D::get_linear_damp); @@ -992,16 +1026,18 @@ void RigidDynamicBody2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "freeze_mode", PROPERTY_HINT_ENUM, "Static,Kinematic"), "set_freeze_mode", "get_freeze_mode"); ADD_GROUP("Linear", "linear_"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "linear_velocity"), "set_linear_velocity", "get_linear_velocity"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "linear_damp_mode", PROPERTY_HINT_ENUM, "Combine,Replace"), "set_linear_damp_mode", "get_linear_damp_mode"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "linear_damp", PROPERTY_HINT_RANGE, "-1,100,0.001,or_greater"), "set_linear_damp", "get_linear_damp"); ADD_GROUP("Angular", "angular_"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "angular_velocity"), "set_angular_velocity", "get_angular_velocity"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "angular_damp_mode", PROPERTY_HINT_ENUM, "Combine,Replace"), "set_angular_damp_mode", "get_angular_damp_mode"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "angular_damp", PROPERTY_HINT_RANGE, "-1,100,0.001,or_greater"), "set_angular_damp", "get_angular_damp"); ADD_GROUP("Applied Forces", "applied_"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "applied_force"), "set_applied_force", "get_applied_force"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "applied_torque"), "set_applied_torque", "get_applied_torque"); - ADD_SIGNAL(MethodInfo("body_shape_entered", PropertyInfo(Variant::RID, "body_rid"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node"), PropertyInfo(Variant::INT, "body_shape"), PropertyInfo(Variant::INT, "local_shape"))); - ADD_SIGNAL(MethodInfo("body_shape_exited", PropertyInfo(Variant::RID, "body_rid"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node"), PropertyInfo(Variant::INT, "body_shape"), PropertyInfo(Variant::INT, "local_shape"))); + ADD_SIGNAL(MethodInfo("body_shape_entered", PropertyInfo(Variant::RID, "body_rid"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node"), PropertyInfo(Variant::INT, "body_shape_index"), PropertyInfo(Variant::INT, "local_shape_index"))); + ADD_SIGNAL(MethodInfo("body_shape_exited", PropertyInfo(Variant::RID, "body_rid"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node"), PropertyInfo(Variant::INT, "body_shape_index"), PropertyInfo(Variant::INT, "local_shape_index"))); ADD_SIGNAL(MethodInfo("body_entered", PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node"))); ADD_SIGNAL(MethodInfo("body_exited", PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node"))); ADD_SIGNAL(MethodInfo("sleeping_state_changed")); @@ -1012,6 +1048,9 @@ void RigidDynamicBody2D::_bind_methods() { BIND_ENUM_CONSTANT(CENTER_OF_MASS_MODE_AUTO); BIND_ENUM_CONSTANT(CENTER_OF_MASS_MODE_CUSTOM); + BIND_ENUM_CONSTANT(DAMP_MODE_COMBINE); + BIND_ENUM_CONSTANT(DAMP_MODE_REPLACE); + BIND_ENUM_CONSTANT(CCD_MODE_DISABLED); BIND_ENUM_CONSTANT(CCD_MODE_CAST_RAY); BIND_ENUM_CONSTANT(CCD_MODE_CAST_SHAPE); @@ -1020,7 +1059,7 @@ void RigidDynamicBody2D::_bind_methods() { void RigidDynamicBody2D::_validate_property(PropertyInfo &property) const { if (center_of_mass_mode != CENTER_OF_MASS_MODE_CUSTOM) { if (property.name == "center_of_mass") { - property.usage = PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL; + property.usage = PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL; } } } @@ -1072,6 +1111,10 @@ bool CharacterBody2D::move_and_slide() { if (bs) { Vector2 local_position = gt.elements[2] - bs->get_transform().elements[2]; current_platform_velocity = bs->get_velocity_at_local_position(local_position); + } else { + // Body is removed or destroyed, invalidate floor. + current_platform_velocity = Vector2(); + platform_rid = RID(); } } else { current_platform_velocity = Vector2(); @@ -1101,7 +1144,7 @@ bool CharacterBody2D::move_and_slide() { } if (motion_mode == MOTION_MODE_GROUNDED) { - _move_and_slide_grounded(delta, was_on_floor, current_platform_velocity); + _move_and_slide_grounded(delta, was_on_floor); } else { _move_and_slide_free(delta); } @@ -1122,14 +1165,11 @@ bool CharacterBody2D::move_and_slide() { return motion_results.size() > 0; } -void CharacterBody2D::_move_and_slide_grounded(double p_delta, bool p_was_on_floor, const Vector2 &p_prev_platform_velocity) { +void CharacterBody2D::_move_and_slide_grounded(double p_delta, bool p_was_on_floor) { Vector2 motion = motion_velocity * p_delta; Vector2 motion_slide_up = motion.slide(up_direction); Vector2 prev_floor_normal = floor_normal; - RID prev_platform_rid = platform_rid; - ObjectID prev_platform_object_id = platform_object_id; - int prev_platform_layer = platform_layer; platform_rid = RID(); platform_object_id = ObjectID(); @@ -1202,12 +1242,8 @@ void CharacterBody2D::_move_and_slide_grounded(double p_delta, bool p_was_on_flo gt.elements[2] -= result.travel; set_global_transform(gt); } - on_floor = true; - platform_rid = prev_platform_rid; - platform_object_id = prev_platform_object_id; - platform_layer = prev_platform_layer; - platform_velocity = p_prev_platform_velocity; - floor_normal = prev_floor_normal; + // Determines if you are on the ground. + _snap_on_floor(true, false); motion_velocity = Vector2(); last_motion = Vector2(); motion = Vector2(); @@ -1281,6 +1317,17 @@ void CharacterBody2D::_move_and_slide_grounded(double p_delta, bool p_was_on_flo _snap_on_floor(p_was_on_floor, vel_dir_facing_up); + // Scales the horizontal velocity according to the wall slope. + if (is_on_wall_only() && motion_slide_up.dot(motion_results.get(0).collision_normal) < 0) { + Vector2 slide_motion = motion_velocity.slide(motion_results.get(0).collision_normal); + if (motion_slide_up.dot(slide_motion) < 0) { + motion_velocity = up_direction * up_direction.dot(motion_velocity); + } else { + // Keeps the vertical motion from motion_velocity and add the horizontal motion of the projection. + motion_velocity = up_direction * up_direction.dot(motion_velocity) + slide_motion.slide(up_direction); + } + } + // Reset the gravity accumulation when touching the ground. if (on_floor && !vel_dir_facing_up) { motion_velocity = motion_velocity.slide(up_direction); @@ -1693,9 +1740,9 @@ void CharacterBody2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "motion_mode", PROPERTY_HINT_ENUM, "Grounded,Free", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), "set_motion_mode", "get_motion_mode"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "up_direction"), "set_up_direction", "get_up_direction"); - ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "motion_velocity", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_motion_velocity", "get_motion_velocity"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "motion_velocity", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_motion_velocity", "get_motion_velocity"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "slide_on_ceiling"), "set_slide_on_ceiling_enabled", "is_slide_on_ceiling_enabled"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "max_slides", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_max_slides", "get_max_slides"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "max_slides", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_max_slides", "get_max_slides"); ADD_GROUP("Free Mode", "free_mode_"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "free_mode_min_slide_angle", PROPERTY_HINT_RANGE, "0,180,0.1,radians", PROPERTY_USAGE_DEFAULT), "set_free_mode_min_slide_angle", "get_free_mode_min_slide_angle"); @@ -1722,11 +1769,11 @@ void CharacterBody2D::_bind_methods() { void CharacterBody2D::_validate_property(PropertyInfo &property) const { if (motion_mode == MOTION_MODE_FREE) { if (property.name.begins_with("floor_") || property.name == "up_direction" || property.name == "slide_on_ceiling") { - property.usage = PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL; + property.usage = PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL; } } else { if (property.name == "free_mode_min_slide_angle") { - property.usage = PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL; + property.usage = PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL; } } } |