diff options
Diffstat (limited to 'scene')
-rw-r--r-- | scene/2d/physics_body_2d.cpp | 47 | ||||
-rw-r--r-- | scene/2d/physics_body_2d.h | 9 |
2 files changed, 29 insertions, 27 deletions
diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp index d8549af66a..713d1daeef 100644 --- a/scene/2d/physics_body_2d.cpp +++ b/scene/2d/physics_body_2d.cpp @@ -32,8 +32,8 @@ #include "core/method_bind_ext.gen.inc" #include "engine.h" +#include "math_funcs.h" #include "scene/scene_string_names.h" - void PhysicsBody2D::_notification(int p_what) { /* @@ -971,11 +971,11 @@ RigidBody2D::~RigidBody2D() { ////////////////////////// -Ref<KinematicCollision2D> KinematicBody2D::_move(const Vector2 &p_motion, bool p_infinite_inertia, bool p_exclude_raycast_shapes, bool p_only_move_if_collided, float p_custom_margin) { +Ref<KinematicCollision2D> KinematicBody2D::_move(const Vector2 &p_motion, bool p_infinite_inertia, bool p_exclude_raycast_shapes) { Collision col; - if (move_and_collide(p_motion, p_infinite_inertia, col, p_exclude_raycast_shapes, p_only_move_if_collided, p_custom_margin)) { + if (move_and_collide(p_motion, p_infinite_inertia, col, p_exclude_raycast_shapes)) { if (motion_cache.is_null()) { motion_cache.instance(); motion_cache->owner = this; @@ -1026,11 +1026,11 @@ 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_only_move_if_collided, float p_custom_margin) { +bool KinematicBody2D::move_and_collide(const Vector2 &p_motion, bool p_infinite_inertia, Collision &r_collision, bool p_exclude_raycast_shapes) { Transform2D gt = get_global_transform(); Physics2DServer::MotionResult result; - bool colliding = Physics2DServer::get_singleton()->body_test_motion(get_rid(), gt, p_motion, p_infinite_inertia, p_custom_margin >= 0 ? p_custom_margin : margin, &result, p_exclude_raycast_shapes); + bool colliding = Physics2DServer::get_singleton()->body_test_motion(get_rid(), gt, p_motion, p_infinite_inertia, margin, &result, p_exclude_raycast_shapes); if (colliding) { r_collision.collider_metadata = result.collider_metadata; @@ -1044,15 +1044,13 @@ bool KinematicBody2D::move_and_collide(const Vector2 &p_motion, bool p_infinite_ r_collision.local_shape = result.collision_local_shape; } - if (!p_only_move_if_collided || colliding) { - gt.elements[2] += result.motion; - set_global_transform(gt); - } + gt.elements[2] += result.motion; + set_global_transform(gt); return colliding; } -Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const Vector2 &p_floor_direction, bool p_infinite_inertia, float p_slope_stop_min_velocity, int p_max_slides, float p_floor_max_angle, const Vector2 &p_snap) { +Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const Vector2 &p_floor_direction, bool p_infinite_inertia, float p_slope_stop_min_velocity, int p_max_slides, float p_floor_max_angle) { Vector2 motion = (floor_velocity + p_linear_velocity) * get_physics_process_delta_time(); Vector2 lv = p_linear_velocity; @@ -1132,20 +1130,23 @@ Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const break; } - if (p_snap != Vector2() && (on_floor || snapped)) { + return lv; +} - Collision collision; - if (move_and_collide(p_snap, p_infinite_inertia, collision, false, true, 0)) { - snapped = true; - } else { - snapped = false; - } +bool KinematicBody2D::snap_to_floor(const Vector2 &p_direction, float p_floor_max_angle) { - } else { - snapped = false; + Transform2D gt = get_global_transform(); + Physics2DServer::MotionResult result; + bool colliding = Physics2DServer::get_singleton()->body_test_motion(get_rid(), gt, p_direction, false, margin, &result, false); + if (colliding) { + gt.elements[2] += result.motion; + if (Math::acos(p_direction.normalized().dot(-result.collision_normal)) < p_floor_max_angle) { + on_floor = true; + } + set_global_transform(gt); } - return lv; + return colliding; } bool KinematicBody2D::is_on_floor() const { @@ -1211,8 +1212,9 @@ Ref<KinematicCollision2D> KinematicBody2D::_get_slide_collision(int p_bounce) { void KinematicBody2D::_bind_methods() { - ClassDB::bind_method(D_METHOD("move_and_collide", "rel_vec", "infinite_inertia", "exclude_raycast_shapes", "only_move_if_collided", "custom_margin"), &KinematicBody2D::_move, DEFVAL(true), DEFVAL(true), DEFVAL(false), DEFVAL(-1.0)); - ClassDB::bind_method(D_METHOD("move_and_slide", "linear_velocity", "floor_normal", "infinite_inertia", "slope_stop_min_velocity", "max_bounces", "floor_max_angle", "snap"), &KinematicBody2D::move_and_slide, DEFVAL(Vector2(0, 0)), DEFVAL(true), DEFVAL(5), DEFVAL(4), DEFVAL(Math::deg2rad((float)45)), DEFVAL(Vector2())); + ClassDB::bind_method(D_METHOD("move_and_collide", "rel_vec", "infinite_inertia", "exclude_raycast_shapes"), &KinematicBody2D::_move, DEFVAL(true), DEFVAL(true)); + ClassDB::bind_method(D_METHOD("move_and_slide", "linear_velocity", "floor_normal", "infinite_inertia", "slope_stop_min_velocity", "max_bounces", "floor_max_angle"), &KinematicBody2D::move_and_slide, DEFVAL(Vector2(0, 0)), DEFVAL(true), DEFVAL(5), DEFVAL(4), DEFVAL(Math::deg2rad((float)45))); + ClassDB::bind_method(D_METHOD("snap_to_floor", "motion", "max_floor_angle"), &KinematicBody2D::snap_to_floor, DEFVAL(Math::deg2rad(45.0))); ClassDB::bind_method(D_METHOD("test_move", "from", "rel_vec", "infinite_inertia"), &KinematicBody2D::test_move); @@ -1238,7 +1240,6 @@ KinematicBody2D::KinematicBody2D() : on_floor = false; on_ceiling = false; on_wall = false; - snapped = false; } KinematicBody2D::~KinematicBody2D() { if (motion_cache.is_valid()) { diff --git a/scene/2d/physics_body_2d.h b/scene/2d/physics_body_2d.h index 5ab07cc754..1873c977a9 100644 --- a/scene/2d/physics_body_2d.h +++ b/scene/2d/physics_body_2d.h @@ -290,21 +290,22 @@ private: bool on_floor; bool on_ceiling; bool on_wall; - bool snapped; + Vector<Collision> colliders; Vector<Ref<KinematicCollision2D> > slide_colliders; Ref<KinematicCollision2D> motion_cache; _FORCE_INLINE_ bool _ignores_mode(Physics2DServer::BodyMode) const; - Ref<KinematicCollision2D> _move(const Vector2 &p_motion, bool p_infinite_inertia = true, bool p_exclude_raycast_shapes = true, bool p_only_move_if_collided = false, float p_custom_margin = -1); + Ref<KinematicCollision2D> _move(const Vector2 &p_motion, bool p_infinite_inertia = true, bool p_exclude_raycast_shapes = true); Ref<KinematicCollision2D> _get_slide_collision(int p_bounce); protected: static void _bind_methods(); public: - bool move_and_collide(const Vector2 &p_motion, bool p_infinite_inertia, Collision &r_collision, bool p_exclude_raycast_shapes = true, bool p_only_move_if_collided = false, float p_custom_margin = -1); + bool move_and_collide(const Vector2 &p_motion, bool p_infinite_inertia, Collision &r_collision, bool p_exclude_raycast_shapes = true); + bool snap_to_floor(const Vector2 &p_direction, float p_floor_max_angle = Math::deg2rad((float)45)); bool test_move(const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia); bool separate_raycast_shapes(bool p_infinite_inertia, Collision &r_collision); @@ -312,7 +313,7 @@ public: void set_safe_margin(float p_margin); float get_safe_margin() const; - Vector2 move_and_slide(const Vector2 &p_linear_velocity, const Vector2 &p_floor_direction = Vector2(0, 0), bool p_infinite_inertia = true, float p_slope_stop_min_velocity = 5, int p_max_slides = 4, float p_floor_max_angle = Math::deg2rad((float)45), const Vector2 &p_snap = Vector2()); + Vector2 move_and_slide(const Vector2 &p_linear_velocity, const Vector2 &p_floor_direction = Vector2(0, 0), bool p_infinite_inertia = true, float p_slope_stop_min_velocity = 5, int p_max_slides = 4, float p_floor_max_angle = Math::deg2rad((float)45)); bool is_on_floor() const; bool is_on_wall() const; bool is_on_ceiling() const; |