diff options
Diffstat (limited to 'scene/2d')
-rw-r--r-- | scene/2d/camera_2d.cpp | 50 | ||||
-rw-r--r-- | scene/2d/camera_2d.h | 4 | ||||
-rw-r--r-- | scene/2d/canvas_item.cpp | 11 | ||||
-rw-r--r-- | scene/2d/canvas_item.h | 4 | ||||
-rw-r--r-- | scene/2d/node_2d.cpp | 53 | ||||
-rw-r--r-- | scene/2d/node_2d.h | 6 | ||||
-rw-r--r-- | scene/2d/physics_body_2d.cpp | 119 | ||||
-rw-r--r-- | scene/2d/physics_body_2d.h | 15 | ||||
-rw-r--r-- | scene/2d/ray_cast_2d.cpp | 36 | ||||
-rw-r--r-- | scene/2d/ray_cast_2d.h | 4 | ||||
-rw-r--r-- | scene/2d/visibility_notifier_2d.cpp | 6 |
11 files changed, 279 insertions, 29 deletions
diff --git a/scene/2d/camera_2d.cpp b/scene/2d/camera_2d.cpp index f98a50e3e0..e576aa10e0 100644 --- a/scene/2d/camera_2d.cpp +++ b/scene/2d/camera_2d.cpp @@ -29,6 +29,8 @@ #include "camera_2d.h" #include "scene/scene_string_names.h" #include "servers/visual_server.h" +#include "core/math/math_funcs.h" +#include <editor/editor_node.h> void Camera2D::_update_scroll() { @@ -114,7 +116,25 @@ Matrix32 Camera2D::get_camera_transform() { camera_pos=new_camera_pos; } - + Point2 screen_offset = (anchor_mode==ANCHOR_MODE_DRAG_CENTER ? (screen_size * 0.5 * zoom) : Point2()); + Rect2 screen_rect(-screen_offset+camera_pos,screen_size*zoom); + + if (offset!=Vector2()) + screen_rect.pos+=offset; + + if (limit_smoothing_enabled) { + if (screen_rect.pos.x < limit[MARGIN_LEFT]) + camera_pos.x -= screen_rect.pos.x - limit[MARGIN_LEFT]; + + if (screen_rect.pos.x + screen_rect.size.x > limit[MARGIN_RIGHT]) + camera_pos.x -= screen_rect.pos.x + screen_rect.size.x - limit[MARGIN_RIGHT]; + + if (screen_rect.pos.y + screen_rect.size.y > limit[MARGIN_BOTTOM]) + camera_pos.y -= screen_rect.pos.y + screen_rect.size.y - limit[MARGIN_BOTTOM]; + + if (screen_rect.pos.y < limit[MARGIN_TOP]) + camera_pos.y -= screen_rect.pos.y - limit[MARGIN_TOP]; + } if (smoothing_enabled && !get_tree()->is_editor_hint()) { @@ -144,19 +164,19 @@ Matrix32 Camera2D::get_camera_transform() { } Rect2 screen_rect(-screen_offset+ret_camera_pos,screen_size*zoom); + if (screen_rect.pos.x < limit[MARGIN_LEFT]) + screen_rect.pos.x = limit[MARGIN_LEFT]; + if (screen_rect.pos.x + screen_rect.size.x > limit[MARGIN_RIGHT]) screen_rect.pos.x = limit[MARGIN_RIGHT] - screen_rect.size.x; if (screen_rect.pos.y + screen_rect.size.y > limit[MARGIN_BOTTOM]) screen_rect.pos.y = limit[MARGIN_BOTTOM] - screen_rect.size.y; - - if (screen_rect.pos.x < limit[MARGIN_LEFT]) - screen_rect.pos.x=limit[MARGIN_LEFT]; - if (screen_rect.pos.y < limit[MARGIN_TOP]) screen_rect.pos.y =limit[MARGIN_TOP]; - + + if (offset!=Vector2()) { screen_rect.pos+=offset; @@ -382,6 +402,17 @@ int Camera2D::get_limit(Margin p_margin) const{ } +void Camera2D::set_limit_smoothing_enabled(bool enable) { + + limit_smoothing_enabled = enable; + _update_scroll(); +} + +bool Camera2D::is_limit_smoothing_enabled() const{ + + return limit_smoothing_enabled; +} + void Camera2D::set_drag_margin(Margin p_margin,float p_drag_margin) { ERR_FAIL_INDEX(p_margin,4); @@ -536,13 +567,15 @@ void Camera2D::_bind_methods() { ObjectTypeDB::bind_method(_MD("_update_scroll"),&Camera2D::_update_scroll); - ObjectTypeDB::bind_method(_MD("_set_current","current"),&Camera2D::_set_current); ObjectTypeDB::bind_method(_MD("is_current"),&Camera2D::is_current); ObjectTypeDB::bind_method(_MD("set_limit","margin","limit"),&Camera2D::set_limit); ObjectTypeDB::bind_method(_MD("get_limit","margin"),&Camera2D::get_limit); + ObjectTypeDB::bind_method(_MD("set_limit_smoothing_enabled","limit_smoothing_enabled"),&Camera2D::set_limit_smoothing_enabled); + ObjectTypeDB::bind_method(_MD("is_limit_smoothing_enabled"),&Camera2D::is_limit_smoothing_enabled); + ObjectTypeDB::bind_method(_MD("set_v_drag_enabled","enabled"),&Camera2D::set_v_drag_enabled); ObjectTypeDB::bind_method(_MD("is_v_drag_enabled"),&Camera2D::is_v_drag_enabled); @@ -587,6 +620,7 @@ void Camera2D::_bind_methods() { ADD_PROPERTYI( PropertyInfo(Variant::INT,"limit/top"),_SCS("set_limit"),_SCS("get_limit"),MARGIN_TOP); ADD_PROPERTYI( PropertyInfo(Variant::INT,"limit/right"),_SCS("set_limit"),_SCS("get_limit"),MARGIN_RIGHT); ADD_PROPERTYI( PropertyInfo(Variant::INT,"limit/bottom"),_SCS("set_limit"),_SCS("get_limit"),MARGIN_BOTTOM); + ADD_PROPERTY( PropertyInfo(Variant::BOOL,"limit/smoothed"),_SCS("set_limit_smoothing_enabled"),_SCS("is_limit_smoothing_enabled") ); ADD_PROPERTY( PropertyInfo(Variant::BOOL,"drag_margin/h_enabled"),_SCS("set_h_drag_enabled"),_SCS("is_h_drag_enabled") ); ADD_PROPERTY( PropertyInfo(Variant::BOOL,"drag_margin/v_enabled"),_SCS("set_v_drag_enabled"),_SCS("is_v_drag_enabled") ); @@ -619,6 +653,7 @@ Camera2D::Camera2D() { limit[MARGIN_TOP]=-10000000; limit[MARGIN_RIGHT]=10000000; limit[MARGIN_BOTTOM]=10000000; + drag_margin[MARGIN_LEFT]=0.2; drag_margin[MARGIN_TOP]=0.2; drag_margin[MARGIN_RIGHT]=0.2; @@ -626,6 +661,7 @@ Camera2D::Camera2D() { camera_pos=Vector2(); first=true; smoothing_enabled=false; + limit_smoothing_enabled=false; smoothing=5.0; zoom = Vector2(1, 1); diff --git a/scene/2d/camera_2d.h b/scene/2d/camera_2d.h index b3f55d798d..9f3e4254bb 100644 --- a/scene/2d/camera_2d.h +++ b/scene/2d/camera_2d.h @@ -61,6 +61,7 @@ protected: float smoothing; bool smoothing_enabled; int limit[4]; + bool limit_smoothing_enabled; float drag_margin[4]; bool h_drag_enabled; @@ -68,7 +69,6 @@ protected: float h_ofs; float v_ofs; - Point2 camera_screen_center; void _update_scroll(); @@ -95,6 +95,8 @@ public: void set_limit(Margin p_margin,int p_limit); int get_limit(Margin p_margin) const; + void set_limit_smoothing_enabled(bool enable); + bool is_limit_smoothing_enabled() const; void set_h_drag_enabled(bool p_enabled); bool is_h_drag_enabled() const; diff --git a/scene/2d/canvas_item.cpp b/scene/2d/canvas_item.cpp index eb4f457975..ed1d606ba8 100644 --- a/scene/2d/canvas_item.cpp +++ b/scene/2d/canvas_item.cpp @@ -650,21 +650,22 @@ int CanvasItem::get_light_mask() const{ } -void CanvasItem::item_rect_changed() { +void CanvasItem::item_rect_changed(bool p_size_changed) { - update(); + if (p_size_changed) + update(); emit_signal(SceneStringNames::get_singleton()->item_rect_changed); } -void CanvasItem::draw_line(const Point2& p_from, const Point2& p_to,const Color& p_color,float p_width) { +void CanvasItem::draw_line(const Point2& p_from, const Point2& p_to,const Color& p_color,float p_width,bool p_antialiased) { if (!drawing) { ERR_EXPLAIN("Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal."); ERR_FAIL(); } - VisualServer::get_singleton()->canvas_item_add_line(canvas_item,p_from,p_to,p_color,p_width); + VisualServer::get_singleton()->canvas_item_add_line(canvas_item,p_from,p_to,p_color,p_width,p_antialiased); } void CanvasItem::draw_rect(const Rect2& p_rect, const Color& p_color) { @@ -1028,7 +1029,7 @@ void CanvasItem::_bind_methods() { ObjectTypeDB::bind_method(_MD("_is_on_top"),&CanvasItem::_is_on_top); //ObjectTypeDB::bind_method(_MD("get_transform"),&CanvasItem::get_transform); - ObjectTypeDB::bind_method(_MD("draw_line","from","to","color","width"),&CanvasItem::draw_line,DEFVAL(1.0)); + ObjectTypeDB::bind_method(_MD("draw_line","from","to","color","width","antialiased"),&CanvasItem::draw_line,DEFVAL(1.0),DEFVAL(false)); ObjectTypeDB::bind_method(_MD("draw_rect","rect","color"),&CanvasItem::draw_rect); ObjectTypeDB::bind_method(_MD("draw_circle","pos","radius","color"),&CanvasItem::draw_circle); ObjectTypeDB::bind_method(_MD("draw_texture","texture:Texture","pos","modulate"),&CanvasItem::draw_texture,DEFVAL(Color(1,1,1,1))); diff --git a/scene/2d/canvas_item.h b/scene/2d/canvas_item.h index b894310ce2..7849a66185 100644 --- a/scene/2d/canvas_item.h +++ b/scene/2d/canvas_item.h @@ -157,7 +157,7 @@ protected: _FORCE_INLINE_ void _notify_transform() { if (!is_inside_tree()) return; _notify_transform(this); if (!block_transform_notify && notify_local_transform) notification(NOTIFICATION_LOCAL_TRANSFORM_CHANGED); } - void item_rect_changed(); + void item_rect_changed(bool p_size_changed=true); void _notification(int p_what); static void _bind_methods(); @@ -207,7 +207,7 @@ public: /* DRAWING API */ - void draw_line(const Point2& p_from, const Point2& p_to,const Color& p_color,float p_width=1.0); + void draw_line(const Point2& p_from, const Point2& p_to, const Color& p_color, float p_width=1.0, bool p_antialiased=false); void draw_rect(const Rect2& p_rect, const Color& p_color); void draw_circle(const Point2& p_pos, float p_radius, const Color& p_color); void draw_texture(const Ref<Texture>& p_texture, const Point2& p_pos, const Color &p_modulate=Color(1,1,1,1)); diff --git a/scene/2d/node_2d.cpp b/scene/2d/node_2d.cpp index 134e0153b3..df43e8e373 100644 --- a/scene/2d/node_2d.cpp +++ b/scene/2d/node_2d.cpp @@ -295,6 +295,53 @@ void Node2D::set_global_pos(const Point2& p_pos) { } } + +float Node2D::get_global_rot() const { + + return get_global_transform().get_rotation(); +} + +void Node2D::set_global_rot(float p_radians) { + + CanvasItem *pi = get_parent_item(); + if (pi) { + const float parent_global_rot = pi->get_global_transform().get_rotation(); + set_rot(p_radians - parent_global_rot); + } else { + set_rot(p_radians); + } +} + + +float Node2D::get_global_rotd() const { + + return Math::rad2deg(get_global_rot()); +} + +void Node2D::set_global_rotd(float p_degrees) { + + set_global_rot(Math::deg2rad(p_degrees)); +} + + +Size2 Node2D::get_global_scale() const { + + return get_global_transform().get_scale(); +} + +void Node2D::set_global_scale(const Size2& p_scale) { + + CanvasItem *pi = get_parent_item(); + if (pi) { + const Size2 parent_global_scale = pi->get_global_transform().get_scale(); + set_scale(p_scale - parent_global_scale); + } else { + set_scale(p_scale); + } + +} + + void Node2D::set_transform(const Matrix32& p_transform) { _mat=p_transform; @@ -398,6 +445,12 @@ void Node2D::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_global_pos","pos"),&Node2D::set_global_pos); ObjectTypeDB::bind_method(_MD("get_global_pos"),&Node2D::get_global_pos); + ObjectTypeDB::bind_method(_MD("set_global_rot","radians"),&Node2D::set_global_rot); + ObjectTypeDB::bind_method(_MD("get_global_rot"),&Node2D::get_global_rot); + ObjectTypeDB::bind_method(_MD("set_global_rotd","degrees"),&Node2D::set_global_rotd); + ObjectTypeDB::bind_method(_MD("get_global_rotd"),&Node2D::get_global_rotd); + ObjectTypeDB::bind_method(_MD("set_global_scale","scale"),&Node2D::set_global_scale); + ObjectTypeDB::bind_method(_MD("get_global_scale"),&Node2D::get_global_scale); ObjectTypeDB::bind_method(_MD("set_transform","xform"),&Node2D::set_transform); ObjectTypeDB::bind_method(_MD("set_global_transform","xform"),&Node2D::set_global_transform); diff --git a/scene/2d/node_2d.h b/scene/2d/node_2d.h index b0c628fd94..aa8d0ef33c 100644 --- a/scene/2d/node_2d.h +++ b/scene/2d/node_2d.h @@ -87,11 +87,17 @@ public: Size2 get_scale() const; Point2 get_global_pos() const; + float get_global_rot() const; + float get_global_rotd() const; + Size2 get_global_scale() const; virtual Rect2 get_item_rect() const; void set_transform(const Matrix32& p_transform); void set_global_transform(const Matrix32& p_transform); void set_global_pos(const Point2& p_pos); + void set_global_rot(float p_radians); + void set_global_rotd(float p_degrees); + void set_global_scale(const Size2& p_scale); void set_z(int p_z); int get_z() const; diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp index 26c4ea385f..0c5c353766 100644 --- a/scene/2d/physics_body_2d.cpp +++ b/scene/2d/physics_body_2d.cpp @@ -436,7 +436,7 @@ bool RigidBody2D::_test_motion(const Vector2& p_motion,float p_margin,const Ref< Physics2DServer::MotionResult *r=NULL; if (p_result.is_valid()) r=p_result->get_result_ptr(); - return Physics2DServer::get_singleton()->body_test_motion(get_rid(),p_motion,p_margin,r); + return Physics2DServer::get_singleton()->body_test_motion(get_rid(),get_global_transform(),p_motion,p_margin,r); } @@ -1057,8 +1057,10 @@ Vector2 KinematicBody2D::get_travel() const { Vector2 KinematicBody2D::move(const Vector2& p_motion) { #if 1 + + Matrix32 gt = get_global_transform(); Physics2DServer::MotionResult result; - colliding = Physics2DServer::get_singleton()->body_test_motion(get_rid(),p_motion,margin,&result); + colliding = Physics2DServer::get_singleton()->body_test_motion(get_rid(),gt,p_motion,margin,&result); collider_metadata=result.collider_metadata; collider_shape=result.collider_shape; @@ -1067,10 +1069,12 @@ Vector2 KinematicBody2D::move(const Vector2& p_motion) { normal=result.collision_normal; collider=result.collider_id; - Matrix32 gt = get_global_transform(); + gt.elements[2]+=result.motion; set_global_transform(gt); travel=result.motion; + + return result.remainder; #else @@ -1081,7 +1085,6 @@ Vector2 KinematicBody2D::move(const Vector2& p_motion) { //this took about a week to get right.. //but is it right? who knows at this point.. - colliding=false; ERR_FAIL_COND_V(!is_inside_tree(),Vector2()); Physics2DDirectSpaceState *dss = Physics2DServer::get_singleton()->space_get_direct_state(get_world_2d()->get_space()); @@ -1099,17 +1102,15 @@ Vector2 KinematicBody2D::move(const Vector2& p_motion) { bool collided=false; uint32_t mask=0; - if (collide_static) + if (true) mask|=Physics2DDirectSpaceState::TYPE_MASK_STATIC_BODY; - if (collide_kinematic) + if (true) mask|=Physics2DDirectSpaceState::TYPE_MASK_KINEMATIC_BODY; - if (collide_rigid) + if (true) mask|=Physics2DDirectSpaceState::TYPE_MASK_RIGID_BODY; - if (collide_character) + if (true) mask|=Physics2DDirectSpaceState::TYPE_MASK_CHARACTER_BODY; -// print_line("motion: "+p_motion+" margin: "+rtos(margin)); - //print_line("margin: "+rtos(margin)); do { @@ -1145,6 +1146,8 @@ Vector2 KinematicBody2D::move(const Vector2& p_motion) { break; } + + Matrix32 gt = get_global_transform(); gt.elements[2]+=recover_motion; set_global_transform(gt); @@ -1191,6 +1194,8 @@ Vector2 KinematicBody2D::move(const Vector2& p_motion) { if (safe>=1) { //not collided colliding=false; + + } else { //it collided, let's get the rest info in unsafe advance @@ -1226,16 +1231,94 @@ Vector2 KinematicBody2D::move(const Vector2& p_motion) { #endif } + + +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 = (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(p_max_bounces) { + + motion=move(motion); + + 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 { + move_and_slide_on_wall=true; + } + + } + + motion=get_collision_normal().slide(motion); + lv=get_collision_normal().slide(lv); + Variant collider = _get_collider(); + if (collider.get_type()!=Variant::NIL) { + move_and_slide_colliders.push_back(collider); + } + + } else { + break; + } + + p_max_bounces--; + if (motion==Vector2()) + break; + } + + return lv; +} + +bool KinematicBody2D::is_move_and_slide_on_floor() const { + + return move_and_slide_on_floor; +} +bool KinematicBody2D::is_move_and_slide_on_wall() const{ + + return move_and_slide_on_wall; +} +bool KinematicBody2D::is_move_and_slide_on_ceiling() const{ + + return move_and_slide_on_ceiling; +} +Array KinematicBody2D::get_move_and_slide_colliders() const{ + + return move_and_slide_colliders; +} + Vector2 KinematicBody2D::move_to(const Vector2& p_position) { return move(p_position-get_global_pos()); } -bool KinematicBody2D::test_move(const Vector2& p_motion) { +bool KinematicBody2D::test_move(const Matrix32& p_from,const Vector2& p_motion) { ERR_FAIL_COND_V(!is_inside_tree(),false); - return Physics2DServer::get_singleton()->body_test_motion(get_rid(),p_motion,margin); + return Physics2DServer::get_singleton()->body_test_motion(get_rid(),p_from,p_motion,margin); } @@ -1300,8 +1383,9 @@ 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","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("test_move","from","rel_vec"),&KinematicBody2D::test_move); ObjectTypeDB::bind_method(_MD("get_travel"),&KinematicBody2D::get_travel); ObjectTypeDB::bind_method(_MD("revert_motion"),&KinematicBody2D::revert_motion); @@ -1313,6 +1397,10 @@ void KinematicBody2D::_bind_methods() { ObjectTypeDB::bind_method(_MD("get_collider:Object"),&KinematicBody2D::_get_collider); ObjectTypeDB::bind_method(_MD("get_collider_shape"),&KinematicBody2D::get_collider_shape); ObjectTypeDB::bind_method(_MD("get_collider_metadata:Variant"),&KinematicBody2D::get_collider_metadata); + ObjectTypeDB::bind_method(_MD("get_move_and_slide_colliders"),&KinematicBody2D::get_move_and_slide_colliders); + ObjectTypeDB::bind_method(_MD("is_move_and_slide_on_floor"),&KinematicBody2D::is_move_and_slide_on_floor); + ObjectTypeDB::bind_method(_MD("is_move_and_slide_on_ceiling"),&KinematicBody2D::is_move_and_slide_on_ceiling); + ObjectTypeDB::bind_method(_MD("is_move_and_slide_on_wall"),&KinematicBody2D::is_move_and_slide_on_wall); ObjectTypeDB::bind_method(_MD("set_collision_margin","pixels"),&KinematicBody2D::set_collision_margin); ObjectTypeDB::bind_method(_MD("get_collision_margin","pixels"),&KinematicBody2D::get_collision_margin); @@ -1330,6 +1418,11 @@ KinematicBody2D::KinematicBody2D() : PhysicsBody2D(Physics2DServer::BODY_MODE_KI collider_shape=0; margin=0.08; + + move_and_slide_on_floor=false; + move_and_slide_on_ceiling=false; + move_and_slide_on_wall=false; + } KinematicBody2D::~KinematicBody2D() { diff --git a/scene/2d/physics_body_2d.h b/scene/2d/physics_body_2d.h index 5af65bff33..ea29d873bd 100644 --- a/scene/2d/physics_body_2d.h +++ b/scene/2d/physics_body_2d.h @@ -302,6 +302,12 @@ class KinematicBody2D : public PhysicsBody2D { Variant collider_metadata; Vector2 travel; + Vector2 move_and_slide_floor_velocity; + bool move_and_slide_on_floor; + bool move_and_slide_on_ceiling; + bool move_and_slide_on_wall; + Array move_and_slide_colliders; + Variant _get_collider() const; _FORCE_INLINE_ bool _ignores_mode(Physics2DServer::BodyMode) const; @@ -313,7 +319,7 @@ public: Vector2 move(const Vector2& p_motion); Vector2 move_to(const Vector2& p_position); - bool test_move(const Vector2& p_motion); + bool test_move(const Matrix32 &p_from, const Vector2& p_motion); bool is_colliding() const; Vector2 get_travel() const; @@ -329,6 +335,13 @@ 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), 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; + Array get_move_and_slide_colliders() const; + + KinematicBody2D(); ~KinematicBody2D(); 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; diff --git a/scene/2d/visibility_notifier_2d.cpp b/scene/2d/visibility_notifier_2d.cpp index 5411950976..852bc187d2 100644 --- a/scene/2d/visibility_notifier_2d.cpp +++ b/scene/2d/visibility_notifier_2d.cpp @@ -40,6 +40,9 @@ void VisibilityNotifier2D::_enter_viewport(Viewport* p_viewport) { ERR_FAIL_COND(viewports.has(p_viewport)); viewports.insert(p_viewport); + if (is_inside_tree() && get_tree()->is_editor_hint()) + return; + if (viewports.size()==1) { emit_signal(SceneStringNames::get_singleton()->enter_screen); @@ -54,6 +57,9 @@ void VisibilityNotifier2D::_exit_viewport(Viewport* p_viewport){ ERR_FAIL_COND(!viewports.has(p_viewport)); viewports.erase(p_viewport); + if (is_inside_tree() && get_tree()->is_editor_hint()) + return; + emit_signal(SceneStringNames::get_singleton()->exit_viewport,p_viewport); if (viewports.size()==0) { emit_signal(SceneStringNames::get_singleton()->exit_screen); |