summaryrefslogtreecommitdiff
path: root/scene/2d
diff options
context:
space:
mode:
Diffstat (limited to 'scene/2d')
-rw-r--r--scene/2d/physics_body_2d.cpp15
-rw-r--r--scene/2d/physics_body_2d.h2
-rw-r--r--scene/2d/ray_cast_2d.cpp36
-rw-r--r--scene/2d/ray_cast_2d.h4
4 files changed, 53 insertions, 4 deletions
diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp
index 75fa6054ad..16df36aa24 100644
--- a/scene/2d/physics_body_2d.cpp
+++ b/scene/2d/physics_body_2d.cpp
@@ -1228,15 +1228,16 @@ Vector2 KinematicBody2D::move(const Vector2& p_motion) {
-Vector2 KinematicBody2D::move_and_slide(const Vector2& p_linear_velocity,const Vector2& p_floor_direction,int p_max_bounces) {
+Vector2 KinematicBody2D::move_and_slide(const Vector2& p_linear_velocity,const Vector2& p_floor_direction,float p_slope_stop_min_velocity,int p_max_bounces) {
- Vector2 motion = p_linear_velocity*get_fixed_process_delta_time();
+ Vector2 motion = (move_and_slide_floor_velocity+p_linear_velocity)*get_fixed_process_delta_time();
Vector2 lv = p_linear_velocity;
move_and_slide_on_floor=false;
move_and_slide_on_ceiling=false;
move_and_slide_on_wall=false;
move_and_slide_colliders.clear();
+ move_and_slide_floor_velocity=Vector2();
while(motion!=Vector2() && p_max_bounces) {
@@ -1244,13 +1245,21 @@ Vector2 KinematicBody2D::move_and_slide(const Vector2& p_linear_velocity,const V
if (is_colliding()) {
+
if (p_floor_direction==Vector2()) {
//all is a wall
move_and_slide_on_wall=true;
} else {
if ( get_collision_normal().dot(p_floor_direction) > Math::cos(Math::deg2rad(45))) { //floor
+
+
move_and_slide_on_floor=true;
move_and_slide_floor_velocity=get_collider_velocity();
+
+ if (get_travel().length()<1 && ABS((lv.x-move_and_slide_floor_velocity.x))<p_slope_stop_min_velocity) {
+ revert_motion();
+ return Vector2();
+ }
} else if ( get_collision_normal().dot(p_floor_direction) < Math::cos(Math::deg2rad(45))) { //ceiling
move_and_slide_on_ceiling=true;
} else {
@@ -1367,7 +1376,7 @@ void KinematicBody2D::_bind_methods() {
ObjectTypeDB::bind_method(_MD("move","rel_vec"),&KinematicBody2D::move);
ObjectTypeDB::bind_method(_MD("move_to","position"),&KinematicBody2D::move_to);
- ObjectTypeDB::bind_method(_MD("move_and_slide","linear_velocity","floor_normal","max_bounces"),&KinematicBody2D::move_and_slide,DEFVAL(Vector2(0,0)),DEFVAL(4));
+ ObjectTypeDB::bind_method(_MD("move_and_slide","linear_velocity","floor_normal","slope_stop_min_velocity","max_bounces"),&KinematicBody2D::move_and_slide,DEFVAL(Vector2(0,0)),DEFVAL(5),DEFVAL(4));
ObjectTypeDB::bind_method(_MD("test_move","rel_vec"),&KinematicBody2D::test_move);
ObjectTypeDB::bind_method(_MD("get_travel"),&KinematicBody2D::get_travel);
diff --git a/scene/2d/physics_body_2d.h b/scene/2d/physics_body_2d.h
index 387267cd09..c088b64858 100644
--- a/scene/2d/physics_body_2d.h
+++ b/scene/2d/physics_body_2d.h
@@ -335,7 +335,7 @@ public:
void set_collision_margin(float p_margin);
float get_collision_margin() const;
- Vector2 move_and_slide(const Vector2& p_linear_velocity,const Vector2& p_floor_direction=Vector2(0,0),int p_max_bounces=4);
+ Vector2 move_and_slide(const Vector2& p_linear_velocity, const Vector2& p_floor_direction=Vector2(0,0), float p_slope_stop_min_velocity=5, int p_max_bounces=4);
bool is_move_and_slide_on_floor() const;
bool is_move_and_slide_on_wall() const;
bool is_move_and_slide_on_ceiling() const;
diff --git a/scene/2d/ray_cast_2d.cpp b/scene/2d/ray_cast_2d.cpp
index 6cda52fa4e..b5d62adfb4 100644
--- a/scene/2d/ray_cast_2d.cpp
+++ b/scene/2d/ray_cast_2d.cpp
@@ -29,6 +29,7 @@
#include "ray_cast_2d.h"
#include "servers/physics_2d_server.h"
#include "collision_object_2d.h"
+#include "physics_body_2d.h"
void RayCast2D::set_cast_to(const Vector2& p_point) {
@@ -106,6 +107,30 @@ bool RayCast2D::is_enabled() const {
return enabled;
}
+void RayCast2D::set_exclude_parent_body(bool p_exclude_parent_body) {
+
+ if (exclude_parent_body==p_exclude_parent_body)
+ return;
+
+ exclude_parent_body=p_exclude_parent_body;
+
+ if (!is_inside_tree())
+ return;
+
+
+
+ if (get_parent()->cast_to<PhysicsBody2D>()) {
+ if (exclude_parent_body)
+ exclude.insert( get_parent()->cast_to<PhysicsBody2D>()->get_rid() );
+ else
+ exclude.erase( get_parent()->cast_to<PhysicsBody2D>()->get_rid() );
+ }
+}
+
+bool RayCast2D::get_exclude_parent_body() const{
+
+ return exclude_parent_body;
+}
void RayCast2D::_notification(int p_what) {
@@ -118,6 +143,12 @@ void RayCast2D::_notification(int p_what) {
else
set_fixed_process(false);
+ if (get_parent()->cast_to<PhysicsBody2D>()) {
+ if (exclude_parent_body)
+ exclude.insert( get_parent()->cast_to<PhysicsBody2D>()->get_rid() );
+ else
+ exclude.erase( get_parent()->cast_to<PhysicsBody2D>()->get_rid() );
+ }
} break;
case NOTIFICATION_EXIT_TREE: {
@@ -254,7 +285,11 @@ void RayCast2D::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_type_mask","mask"),&RayCast2D::set_type_mask);
ObjectTypeDB::bind_method(_MD("get_type_mask"),&RayCast2D::get_type_mask);
+ ObjectTypeDB::bind_method(_MD("set_exclude_parent_body","mask"),&RayCast2D::set_exclude_parent_body);
+ ObjectTypeDB::bind_method(_MD("get_exclude_parent_body"),&RayCast2D::get_exclude_parent_body);
+
ADD_PROPERTY(PropertyInfo(Variant::BOOL,"enabled"),_SCS("set_enabled"),_SCS("is_enabled"));
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL,"exclude_parent"),_SCS("set_exclude_parent_body"),_SCS("get_exclude_parent_body"));
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2,"cast_to"),_SCS("set_cast_to"),_SCS("get_cast_to"));
ADD_PROPERTY(PropertyInfo(Variant::INT,"layer_mask",PROPERTY_HINT_ALL_FLAGS),_SCS("set_layer_mask"),_SCS("get_layer_mask"));
ADD_PROPERTY(PropertyInfo(Variant::INT,"type_mask",PROPERTY_HINT_FLAGS,"Static,Kinematic,Rigid,Character,Area"),_SCS("set_type_mask"),_SCS("get_type_mask"));
@@ -269,4 +304,5 @@ RayCast2D::RayCast2D() {
layer_mask=1;
type_mask=Physics2DDirectSpaceState::TYPE_MASK_COLLISION;
cast_to=Vector2(0,50);
+ exclude_parent_body=true;
}
diff --git a/scene/2d/ray_cast_2d.h b/scene/2d/ray_cast_2d.h
index 54ec42c53e..e1caa8b63e 100644
--- a/scene/2d/ray_cast_2d.h
+++ b/scene/2d/ray_cast_2d.h
@@ -45,6 +45,7 @@ class RayCast2D : public Node2D {
Set<RID> exclude;
uint32_t layer_mask;
uint32_t type_mask;
+ bool exclude_parent_body;
Vector2 cast_to;
@@ -66,6 +67,9 @@ public:
void set_type_mask(uint32_t p_mask);
uint32_t get_type_mask() const;
+ void set_exclude_parent_body(bool p_exclude_parent_body);
+ bool get_exclude_parent_body() const;
+
bool is_colliding() const;
Object *get_collider() const;
int get_collider_shape() const;