diff options
Diffstat (limited to 'scene/2d/physics_body_2d.cpp')
| -rw-r--r-- | scene/2d/physics_body_2d.cpp | 188 |
1 files changed, 103 insertions, 85 deletions
diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp index d0bebd3354..3a4f397fe0 100644 --- a/scene/2d/physics_body_2d.cpp +++ b/scene/2d/physics_body_2d.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -32,8 +32,11 @@ #include "core/core_string_names.h" #include "core/engine.h" +#include "core/list.h" #include "core/math/math_funcs.h" #include "core/method_bind_ext.gen.inc" +#include "core/object.h" +#include "core/rid.h" #include "scene/scene_string_names.h" void PhysicsBody2D::_notification(int p_what) { @@ -65,6 +68,8 @@ void PhysicsBody2D::_bind_methods() { ClassDB::bind_method(D_METHOD("_set_layers", "mask"), &PhysicsBody2D::_set_layers); ClassDB::bind_method(D_METHOD("_get_layers"), &PhysicsBody2D::_get_layers); + + ClassDB::bind_method(D_METHOD("get_collision_exceptions"), &PhysicsBody2D::get_collision_exceptions); ClassDB::bind_method(D_METHOD("add_collision_exception_with", "body"), &PhysicsBody2D::add_collision_exception_with); ClassDB::bind_method(D_METHOD("remove_collision_exception_with", "body"), &PhysicsBody2D::remove_collision_exception_with); ADD_PROPERTY(PropertyInfo(Variant::INT, "layers", PROPERTY_HINT_LAYERS_2D_PHYSICS, "", 0), "_set_layers", "_get_layers"); //for backwards compat @@ -134,14 +139,25 @@ PhysicsBody2D::PhysicsBody2D(Physics2DServer::BodyMode p_mode) : set_pickable(false); } +Array PhysicsBody2D::get_collision_exceptions() { + List<RID> exceptions; + Physics2DServer::get_singleton()->body_get_collision_exceptions(get_rid(), &exceptions); + Array ret; + for (List<RID>::Element *E = exceptions.front(); E; E = E->next()) { + RID body = E->get(); + ObjectID instance_id = Physics2DServer::get_singleton()->body_get_object_instance_id(body); + Object *obj = ObjectDB::get_instance(instance_id); + PhysicsBody2D *physics_body = Object::cast_to<PhysicsBody2D>(obj); + ret.append(physics_body); + } + return ret; +} + void PhysicsBody2D::add_collision_exception_with(Node *p_node) { ERR_FAIL_NULL(p_node); PhysicsBody2D *physics_body = Object::cast_to<PhysicsBody2D>(p_node); - if (!physics_body) { - ERR_EXPLAIN("Collision exception only works between two objects of PhysicsBody type"); - } - ERR_FAIL_COND(!physics_body); + ERR_FAIL_COND_MSG(!physics_body, "Collision exception only works between two objects of PhysicsBody type."); Physics2DServer::get_singleton()->body_add_collision_exception(get_rid(), physics_body->get_rid()); } @@ -149,10 +165,7 @@ void PhysicsBody2D::remove_collision_exception_with(Node *p_node) { ERR_FAIL_NULL(p_node); PhysicsBody2D *physics_body = Object::cast_to<PhysicsBody2D>(p_node); - if (!physics_body) { - ERR_EXPLAIN("Collision exception only works between two objects of PhysicsBody type"); - } - ERR_FAIL_COND(!physics_body); + ERR_FAIL_COND_MSG(!physics_body, "Collision exception only works between two objects of PhysicsBody type."); Physics2DServer::get_singleton()->body_remove_collision_exception(get_rid(), physics_body->get_rid()); } @@ -180,14 +193,13 @@ real_t StaticBody2D::get_constant_angular_velocity() const { #ifndef DISABLE_DEPRECATED void StaticBody2D::set_friction(real_t p_friction) { - if (p_friction == 1.0) { // default value, don't create an override for that + if (p_friction == 1.0 && physics_material_override.is_null()) { // default value, don't create an override for that return; } - ERR_EXPLAIN("The method set_friction has been deprecated and will be removed in the future, use physics material instead.") - WARN_DEPRECATED + WARN_DEPRECATED_MSG("The method set_friction has been deprecated and will be removed in the future, use physics material instead."); - ERR_FAIL_COND(p_friction < 0 || p_friction > 1); + ERR_FAIL_COND_MSG(p_friction < 0 || p_friction > 1, "Friction must be between 0 and 1."); if (physics_material_override.is_null()) { physics_material_override.instance(); @@ -198,8 +210,7 @@ void StaticBody2D::set_friction(real_t p_friction) { real_t StaticBody2D::get_friction() const { - ERR_EXPLAIN("The method get_friction has been deprecated and will be removed in the future, use physics material instead.") - WARN_DEPRECATED + WARN_DEPRECATED_MSG("The method get_friction has been deprecated and will be removed in the future, use physics material instead."); if (physics_material_override.is_null()) { return 1; @@ -210,14 +221,13 @@ real_t StaticBody2D::get_friction() const { void StaticBody2D::set_bounce(real_t p_bounce) { - if (p_bounce == 0.0) { // default value, don't create an override for that + if (p_bounce == 0.0 && physics_material_override.is_null()) { // default value, don't create an override for that return; } - ERR_EXPLAIN("The method set_bounce has been deprecated and will be removed in the future, use physics material instead.") - WARN_DEPRECATED + WARN_DEPRECATED_MSG("The method set_bounce has been deprecated and will be removed in the future, use physics material instead."); - ERR_FAIL_COND(p_bounce < 0 || p_bounce > 1); + ERR_FAIL_COND_MSG(p_bounce < 0 || p_bounce > 1, "Bounce must be between 0 and 1."); if (physics_material_override.is_null()) { physics_material_override.instance(); @@ -228,8 +238,7 @@ void StaticBody2D::set_bounce(real_t p_bounce) { real_t StaticBody2D::get_bounce() const { - ERR_EXPLAIN("The method get_bounce has been deprecated and will be removed in the future, use physics material instead.") - WARN_DEPRECATED + WARN_DEPRECATED_MSG("The method get_bounce has been deprecated and will be removed in the future, use physics material instead."); if (physics_material_override.is_null()) { return 0; @@ -280,10 +289,10 @@ void StaticBody2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "constant_linear_velocity"), "set_constant_linear_velocity", "get_constant_linear_velocity"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "constant_angular_velocity"), "set_constant_angular_velocity", "get_constant_angular_velocity"); #ifndef DISABLE_DEPRECATED - ADD_PROPERTYNO(PropertyInfo(Variant::REAL, "friction", PROPERTY_HINT_RANGE, "0,1,0.01", 0), "set_friction", "get_friction"); - ADD_PROPERTYNZ(PropertyInfo(Variant::REAL, "bounce", PROPERTY_HINT_RANGE, "0,1,0.01", 0), "set_bounce", "get_bounce"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "friction", PROPERTY_HINT_RANGE, "0,1,0.01", 0), "set_friction", "get_friction"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "bounce", PROPERTY_HINT_RANGE, "0,1,0.01", 0), "set_bounce", "get_bounce"); #endif // DISABLE_DEPRECATED - ADD_PROPERTYNZ(PropertyInfo(Variant::OBJECT, "physics_material_override", PROPERTY_HINT_RESOURCE_TYPE, "PhysicsMaterial"), "set_physics_material_override", "get_physics_material_override"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "physics_material_override", PROPERTY_HINT_RESOURCE_TYPE, "PhysicsMaterial"), "set_physics_material_override", "get_physics_material_override"); } StaticBody2D::StaticBody2D() : @@ -585,7 +594,7 @@ real_t RigidBody2D::get_mass() const { void RigidBody2D::set_inertia(real_t p_inertia) { - ERR_FAIL_COND(p_inertia <= 0); + ERR_FAIL_COND(p_inertia < 0); Physics2DServer::get_singleton()->body_set_param(get_rid(), Physics2DServer::BODY_PARAM_INERTIA, p_inertia); } @@ -607,14 +616,13 @@ real_t RigidBody2D::get_weight() const { #ifndef DISABLE_DEPRECATED void RigidBody2D::set_friction(real_t p_friction) { - if (p_friction == 1.0) { // default value, don't create an override for that + if (p_friction == 1.0 && physics_material_override.is_null()) { // default value, don't create an override for that return; } - ERR_EXPLAIN("The method set_friction has been deprecated and will be removed in the future, use physics material instead.") - WARN_DEPRECATED + WARN_DEPRECATED_MSG("The method set_friction has been deprecated and will be removed in the future, use physics material instead."); - ERR_FAIL_COND(p_friction < 0 || p_friction > 1); + ERR_FAIL_COND_MSG(p_friction < 0 || p_friction > 1, "Friction must be between 0 and 1."); if (physics_material_override.is_null()) { physics_material_override.instance(); @@ -624,8 +632,7 @@ void RigidBody2D::set_friction(real_t p_friction) { } real_t RigidBody2D::get_friction() const { - ERR_EXPLAIN("The method get_friction has been deprecated and will be removed in the future, use physics material instead.") - WARN_DEPRECATED + WARN_DEPRECATED_MSG("The method get_friction has been deprecated and will be removed in the future, use physics material instead."); if (physics_material_override.is_null()) { return 1; @@ -636,12 +643,11 @@ real_t RigidBody2D::get_friction() const { void RigidBody2D::set_bounce(real_t p_bounce) { - if (p_bounce == 0.0) { // default value, don't create an override for that + if (p_bounce == 0.0 && physics_material_override.is_null()) { // default value, don't create an override for that return; } - ERR_EXPLAIN("The method set_bounce has been deprecated and will be removed in the future, use physics material instead.") - WARN_DEPRECATED + WARN_DEPRECATED_MSG("The method set_bounce has been deprecated and will be removed in the future, use physics material instead."); ERR_FAIL_COND(p_bounce < 0 || p_bounce > 1); @@ -653,8 +659,7 @@ void RigidBody2D::set_bounce(real_t p_bounce) { } real_t RigidBody2D::get_bounce() const { - ERR_EXPLAIN("The method get_bounce has been deprecated and will be removed in the future, use physics material instead.") - WARN_DEPRECATED + WARN_DEPRECATED_MSG("The method get_bounce has been deprecated and will be removed in the future, use physics material instead."); if (physics_material_override.is_null()) { return 0; @@ -886,10 +891,7 @@ void RigidBody2D::set_contact_monitor(bool p_enabled) { if (!p_enabled) { - if (contact_monitor->locked) { - ERR_EXPLAIN("Can't disable contact monitoring during in/out callback. Use call_deferred(\"set_contact_monitor\",false) instead"); - } - ERR_FAIL_COND(contact_monitor->locked); + ERR_FAIL_COND_MSG(contact_monitor->locked, "Can't disable contact monitoring during in/out callback. Use call_deferred(\"set_contact_monitor\", false) instead."); for (Map<ObjectID, BodyState>::Element *E = contact_monitor->body_map.front(); E; E = E->next()) { @@ -944,7 +946,7 @@ String RigidBody2D::get_configuration_warning() const { if ((get_mode() == MODE_RIGID || get_mode() == MODE_CHARACTER) && (ABS(t.elements[0].length() - 1.0) > 0.05 || ABS(t.elements[1].length() - 1.0) > 0.05)) { if (warning != String()) { - warning += "\n"; + warning += "\n\n"; } warning += TTR("Size changes to RigidBody2D (in character or rigid modes) will be overridden by the physics engine when running.\nChange the size in children collision shapes instead."); } @@ -1042,10 +1044,10 @@ void RigidBody2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::REAL, "inertia", PROPERTY_HINT_EXP_RANGE, "0.01,65535,0.01", 0), "set_inertia", "get_inertia"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "weight", PROPERTY_HINT_EXP_RANGE, "0.01,65535,0.01", PROPERTY_USAGE_EDITOR), "set_weight", "get_weight"); #ifndef DISABLE_DEPRECATED - ADD_PROPERTYNO(PropertyInfo(Variant::REAL, "friction", PROPERTY_HINT_RANGE, "0,1,0.01", 0), "set_friction", "get_friction"); - ADD_PROPERTYNZ(PropertyInfo(Variant::REAL, "bounce", PROPERTY_HINT_RANGE, "0,1,0.01", 0), "set_bounce", "get_bounce"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "friction", PROPERTY_HINT_RANGE, "0,1,0.01", 0), "set_friction", "get_friction"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "bounce", PROPERTY_HINT_RANGE, "0,1,0.01", 0), "set_bounce", "get_bounce"); #endif // DISABLE_DEPRECATED - ADD_PROPERTYNZ(PropertyInfo(Variant::OBJECT, "physics_material_override", PROPERTY_HINT_RESOURCE_TYPE, "PhysicsMaterial"), "set_physics_material_override", "get_physics_material_override"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "physics_material_override", PROPERTY_HINT_RESOURCE_TYPE, "PhysicsMaterial"), "set_physics_material_override", "get_physics_material_override"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "gravity_scale", PROPERTY_HINT_RANGE, "-128,128,0.01"), "set_gravity_scale", "get_gravity_scale"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "custom_integrator"), "set_use_custom_integrator", "is_using_custom_integrator"); ADD_PROPERTY(PropertyInfo(Variant::INT, "continuous_cd", PROPERTY_HINT_ENUM, "Disabled,Cast Ray,Cast Shape"), "set_continuous_collision_detection_mode", "get_continuous_collision_detection_mode"); @@ -1055,13 +1057,13 @@ void RigidBody2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "can_sleep"), "set_can_sleep", "is_able_to_sleep"); ADD_GROUP("Linear", "linear_"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "linear_velocity"), "set_linear_velocity", "get_linear_velocity"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "linear_damp", PROPERTY_HINT_RANGE, "-1,128,0.01"), "set_linear_damp", "get_linear_damp"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "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::REAL, "angular_velocity"), "set_angular_velocity", "get_angular_velocity"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "angular_damp", PROPERTY_HINT_RANGE, "-1,128,0.01"), "set_angular_damp", "get_angular_damp"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "angular_damp", PROPERTY_HINT_RANGE, "-1,100,0.001,or_greater"), "set_angular_damp", "get_angular_damp"); ADD_GROUP("Applied Forces", "applied_"); - ADD_PROPERTYNZ(PropertyInfo(Variant::VECTOR2, "applied_force"), "set_applied_force", "get_applied_force"); - ADD_PROPERTYNZ(PropertyInfo(Variant::REAL, "applied_torque"), "set_applied_torque", "get_applied_torque"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "applied_force"), "set_applied_force", "get_applied_force"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "applied_torque"), "set_applied_torque", "get_applied_torque"); ADD_SIGNAL(MethodInfo("body_shape_entered", PropertyInfo(Variant::INT, "body_id"), 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::INT, "body_id"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node"), PropertyInfo(Variant::INT, "body_shape"), PropertyInfo(Variant::INT, "local_shape"))); @@ -1179,6 +1181,9 @@ bool KinematicBody2D::separate_raycast_shapes(bool p_infinite_inertia, Collision bool KinematicBody2D::move_and_collide(const Vector2 &p_motion, bool p_infinite_inertia, Collision &r_collision, bool p_exclude_raycast_shapes, bool p_test_only) { + if (sync_to_physics) { + ERR_PRINT("Functions move_and_slide and move_and_collide do not work together with 'sync to physics' option. Please read the documentation."); + } Transform2D gt = get_global_transform(); Physics2DServer::MotionResult result; bool colliding = Physics2DServer::get_singleton()->body_test_motion(get_rid(), gt, p_motion, p_infinite_inertia, margin, &result, p_exclude_raycast_shapes); @@ -1204,10 +1209,10 @@ bool KinematicBody2D::move_and_collide(const Vector2 &p_motion, bool p_infinite_ return colliding; } -//so, if you pass 45 as limit, avoid numerical precision erros when angle is 45. +//so, if you pass 45 as limit, avoid numerical precision errors when angle is 45. #define FLOOR_ANGLE_THRESHOLD 0.01 -Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const Vector2 &p_floor_direction, bool p_infinite_inertia, bool p_stop_on_slope, int p_max_slides, float p_floor_max_angle) { +Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const Vector2 &p_floor_direction, bool p_stop_on_slope, int p_max_slides, float p_floor_max_angle, bool p_infinite_inertia) { Vector2 floor_motion = floor_velocity; if (on_floor && on_floor_body.is_valid()) { @@ -1218,7 +1223,8 @@ Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const } } - Vector2 motion = (floor_motion + p_linear_velocity) * get_physics_process_delta_time(); + // Hack in order to work with calling from _process as well as from _physics_process; calling from thread is risky + Vector2 motion = (floor_motion + p_linear_velocity) * (Engine::get_singleton()->is_in_physics_frame() ? get_physics_process_delta_time() : get_process_delta_time()); Vector2 lv = p_linear_velocity; on_floor = false; @@ -1252,54 +1258,40 @@ Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const if (collided) { found_collision = true; - } - - if (collided) { colliders.push_back(collision); motion = collision.remainder; - bool is_on_slope = false; if (p_floor_direction == Vector2()) { //all is a wall on_wall = true; } else { - if (collision.normal.dot(p_floor_direction) >= Math::cos(p_floor_max_angle + FLOOR_ANGLE_THRESHOLD)) { //floor + if (Math::acos(collision.normal.dot(p_floor_direction)) <= p_floor_max_angle + FLOOR_ANGLE_THRESHOLD) { //floor on_floor = true; on_floor_body = collision.collider_rid; floor_velocity = collision.collider_vel; if (p_stop_on_slope) { - if (Vector2() == lv_n + p_floor_direction) { + if ((lv_n + p_floor_direction).length() < 0.01 && collision.travel.length() < 1) { Transform2D gt = get_global_transform(); - gt.elements[2] -= collision.travel; + gt.elements[2] -= collision.travel.project(p_floor_direction.tangent()); set_global_transform(gt); return Vector2(); } } - is_on_slope = true; - - } else if (collision.normal.dot(-p_floor_direction) >= Math::cos(p_floor_max_angle + FLOOR_ANGLE_THRESHOLD)) { //ceiling + } else if (Math::acos(collision.normal.dot(-p_floor_direction)) <= p_floor_max_angle + FLOOR_ANGLE_THRESHOLD) { //ceiling on_ceiling = true; } else { on_wall = true; } } - if (p_stop_on_slope && is_on_slope) { - motion = motion.slide(p_floor_direction); - lv = lv.slide(p_floor_direction); - } else { - Vector2 n = collision.normal; - motion = motion.slide(n); - lv = lv.slide(n); - } + Vector2 n = collision.normal; + motion = motion.slide(n); + lv = lv.slide(n); } - - if (p_stop_on_slope) - break; } if (!found_collision) { @@ -1313,11 +1305,11 @@ Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const return lv; } -Vector2 KinematicBody2D::move_and_slide_with_snap(const Vector2 &p_linear_velocity, const Vector2 &p_snap, const Vector2 &p_floor_direction, bool p_infinite_inertia, bool p_stop_on_slope, int p_max_slides, float p_floor_max_angle) { +Vector2 KinematicBody2D::move_and_slide_with_snap(const Vector2 &p_linear_velocity, const Vector2 &p_snap, const Vector2 &p_floor_direction, bool p_stop_on_slope, int p_max_slides, float p_floor_max_angle, bool p_infinite_inertia) { bool was_on_floor = on_floor; - Vector2 ret = move_and_slide(p_linear_velocity, p_floor_direction, p_infinite_inertia, p_stop_on_slope, p_max_slides, p_floor_max_angle); + Vector2 ret = move_and_slide(p_linear_velocity, p_floor_direction, p_stop_on_slope, p_max_slides, p_floor_max_angle, p_infinite_inertia); if (!was_on_floor || p_snap == Vector2()) { return ret; } @@ -1326,13 +1318,27 @@ Vector2 KinematicBody2D::move_and_slide_with_snap(const Vector2 &p_linear_veloci Transform2D gt = get_global_transform(); if (move_and_collide(p_snap, p_infinite_inertia, col, false, true)) { - gt.elements[2] += col.travel; - if (p_floor_direction != Vector2() && Math::acos(p_floor_direction.normalized().dot(col.normal)) < p_floor_max_angle) { - on_floor = true; - on_floor_body = col.collider_rid; - floor_velocity = col.collider_vel; + bool apply = true; + if (p_floor_direction != Vector2()) { + if (Math::acos(p_floor_direction.normalized().dot(col.normal)) < p_floor_max_angle) { + on_floor = true; + on_floor_body = col.collider_rid; + floor_velocity = col.collider_vel; + if (p_stop_on_slope) { + // move and collide may stray the object a bit because of pre un-stucking, + // so only ensure that motion happens on floor direction in this case. + col.travel = p_floor_direction * p_floor_direction.dot(col.travel); + } + + } else { + apply = false; + } + } + + if (apply) { + gt.elements[2] += col.travel; + set_global_transform(gt); } - set_global_transform(gt); } return ret; @@ -1405,6 +1411,10 @@ void KinematicBody2D::set_sync_to_physics(bool p_enable) { return; } sync_to_physics = p_enable; + + if (Engine::get_singleton()->is_editor_hint()) + return; + if (p_enable) { Physics2DServer::get_singleton()->body_set_force_integration_callback(get_rid(), this, "_direct_state_changed"); set_only_update_transform_changes(true); @@ -1436,6 +1446,14 @@ void KinematicBody2D::_direct_state_changed(Object *p_state) { void KinematicBody2D::_notification(int p_what) { if (p_what == NOTIFICATION_ENTER_TREE) { last_valid_transform = get_global_transform(); + + // Reset move_and_slide() data. + on_floor = false; + on_floor_body = RID(); + on_ceiling = false; + on_wall = false; + colliders.clear(); + floor_velocity = Vector2(); } if (p_what == NOTIFICATION_LOCAL_TRANSFORM_CHANGED) { @@ -1451,10 +1469,10 @@ void KinematicBody2D::_notification(int p_what) { void KinematicBody2D::_bind_methods() { ClassDB::bind_method(D_METHOD("move_and_collide", "rel_vec", "infinite_inertia", "exclude_raycast_shapes", "test_only"), &KinematicBody2D::_move, DEFVAL(true), DEFVAL(true), DEFVAL(false)); - ClassDB::bind_method(D_METHOD("move_and_slide", "linear_velocity", "floor_normal", "infinite_inertia", "stop_on_slope", "max_bounces", "floor_max_angle"), &KinematicBody2D::move_and_slide, DEFVAL(Vector2(0, 0)), DEFVAL(true), DEFVAL(false), DEFVAL(4), DEFVAL(Math::deg2rad((float)45))); - ClassDB::bind_method(D_METHOD("move_and_slide_with_snap", "linear_velocity", "snap", "floor_normal", "infinite_inertia", "stop_on_slope", "max_bounces", "floor_max_angle"), &KinematicBody2D::move_and_slide_with_snap, DEFVAL(Vector2(0, 0)), DEFVAL(true), DEFVAL(false), DEFVAL(4), DEFVAL(Math::deg2rad((float)45))); + ClassDB::bind_method(D_METHOD("move_and_slide", "linear_velocity", "floor_normal", "stop_on_slope", "max_slides", "floor_max_angle", "infinite_inertia"), &KinematicBody2D::move_and_slide, DEFVAL(Vector2(0, 0)), DEFVAL(false), DEFVAL(4), DEFVAL(Math::deg2rad((float)45)), DEFVAL(true)); + ClassDB::bind_method(D_METHOD("move_and_slide_with_snap", "linear_velocity", "snap", "floor_normal", "stop_on_slope", "max_slides", "floor_max_angle", "infinite_inertia"), &KinematicBody2D::move_and_slide_with_snap, DEFVAL(Vector2(0, 0)), DEFVAL(false), DEFVAL(4), DEFVAL(Math::deg2rad((float)45)), DEFVAL(true)); - ClassDB::bind_method(D_METHOD("test_move", "from", "rel_vec", "infinite_inertia"), &KinematicBody2D::test_move); + ClassDB::bind_method(D_METHOD("test_move", "from", "rel_vec", "infinite_inertia"), &KinematicBody2D::test_move, DEFVAL(true)); ClassDB::bind_method(D_METHOD("is_on_floor"), &KinematicBody2D::is_on_floor); ClassDB::bind_method(D_METHOD("is_on_ceiling"), &KinematicBody2D::is_on_ceiling); @@ -1514,7 +1532,7 @@ Vector2 KinematicCollision2D::get_remainder() const { return collision.remainder; } Object *KinematicCollision2D::get_local_shape() const { - ERR_FAIL_COND_V(!owner, NULL); + if (!owner) return NULL; uint32_t ownerid = owner->shape_find_owner(collision.local_shape); return owner->shape_owner_get_owner(ownerid); } |