diff options
Diffstat (limited to 'scene/2d/visibility_notifier_2d.cpp')
-rw-r--r-- | scene/2d/visibility_notifier_2d.cpp | 96 |
1 files changed, 43 insertions, 53 deletions
diff --git a/scene/2d/visibility_notifier_2d.cpp b/scene/2d/visibility_notifier_2d.cpp index c374dd5faa..75154c7acb 100644 --- a/scene/2d/visibility_notifier_2d.cpp +++ b/scene/2d/visibility_notifier_2d.cpp @@ -49,12 +49,12 @@ bool VisibilityNotifier2D::_edit_use_rect() const { #endif void VisibilityNotifier2D::_enter_viewport(Viewport *p_viewport) { - ERR_FAIL_COND(viewports.has(p_viewport)); viewports.insert(p_viewport); - if (is_inside_tree() && Engine::get_singleton()->is_editor_hint()) + if (is_inside_tree() && Engine::get_singleton()->is_editor_hint()) { return; + } if (viewports.size() == 1) { emit_signal(SceneStringNames::get_singleton()->screen_entered); @@ -65,12 +65,12 @@ void VisibilityNotifier2D::_enter_viewport(Viewport *p_viewport) { } void VisibilityNotifier2D::_exit_viewport(Viewport *p_viewport) { - ERR_FAIL_COND(!viewports.has(p_viewport)); viewports.erase(p_viewport); - if (is_inside_tree() && Engine::get_singleton()->is_editor_hint()) + if (is_inside_tree() && Engine::get_singleton()->is_editor_hint()) { return; + } emit_signal(SceneStringNames::get_singleton()->viewport_exited, p_viewport); if (viewports.size() == 0) { @@ -81,7 +81,6 @@ void VisibilityNotifier2D::_exit_viewport(Viewport *p_viewport) { } void VisibilityNotifier2D::set_rect(const Rect2 &p_rect) { - rect = p_rect; if (is_inside_tree()) { get_world_2d()->_update_notifier(this, get_global_transform().xform(rect)); @@ -95,44 +94,35 @@ void VisibilityNotifier2D::set_rect(const Rect2 &p_rect) { } Rect2 VisibilityNotifier2D::get_rect() const { - return rect; } void VisibilityNotifier2D::_notification(int p_what) { - switch (p_what) { case NOTIFICATION_ENTER_TREE: { - //get_world_2d()-> get_world_2d()->_register_notifier(this, get_global_transform().xform(rect)); } break; case NOTIFICATION_TRANSFORM_CHANGED: { - //get_world_2d()-> get_world_2d()->_update_notifier(this, get_global_transform().xform(rect)); } break; case NOTIFICATION_DRAW: { - if (Engine::get_singleton()->is_editor_hint()) { - draw_rect(rect, Color(1, 0.5, 1, 0.2)); } } break; case NOTIFICATION_EXIT_TREE: { - get_world_2d()->_remove_notifier(this); } break; } } bool VisibilityNotifier2D::is_on_screen() const { - return viewports.size() > 0; } void VisibilityNotifier2D::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_rect", "rect"), &VisibilityNotifier2D::set_rect); ClassDB::bind_method(D_METHOD("get_rect"), &VisibilityNotifier2D::get_rect); ClassDB::bind_method(D_METHOD("is_on_screen"), &VisibilityNotifier2D::is_on_screen); @@ -146,7 +136,6 @@ void VisibilityNotifier2D::_bind_methods() { } VisibilityNotifier2D::VisibilityNotifier2D() { - rect = Rect2(-10, -10, 20, 20); set_notify_transform(true); } @@ -154,44 +143,42 @@ VisibilityNotifier2D::VisibilityNotifier2D() { ////////////////////////////////////// void VisibilityEnabler2D::_screen_enter() { - for (Map<Node *, Variant>::Element *E = nodes.front(); E; E = E->next()) { - _change_node_state(E->key(), true); } - if (enabler[ENABLER_PARENT_PHYSICS_PROCESS] && get_parent()) + if (enabler[ENABLER_PARENT_PHYSICS_PROCESS] && get_parent()) { get_parent()->set_physics_process(true); - if (enabler[ENABLER_PARENT_PROCESS] && get_parent()) + } + if (enabler[ENABLER_PARENT_PROCESS] && get_parent()) { get_parent()->set_process(true); + } visible = true; } void VisibilityEnabler2D::_screen_exit() { - for (Map<Node *, Variant>::Element *E = nodes.front(); E; E = E->next()) { - _change_node_state(E->key(), false); } - if (enabler[ENABLER_PARENT_PHYSICS_PROCESS] && get_parent()) + if (enabler[ENABLER_PARENT_PHYSICS_PROCESS] && get_parent()) { get_parent()->set_physics_process(false); - if (enabler[ENABLER_PARENT_PROCESS] && get_parent()) + } + if (enabler[ENABLER_PARENT_PROCESS] && get_parent()) { get_parent()->set_process(false); + } visible = false; } void VisibilityEnabler2D::_find_nodes(Node *p_node) { - bool add = false; Variant meta; { RigidBody2D *rb2d = Object::cast_to<RigidBody2D>(p_node); if (rb2d && ((rb2d->get_mode() == RigidBody2D::MODE_CHARACTER || rb2d->get_mode() == RigidBody2D::MODE_RIGID))) { - add = true; meta = rb2d->get_mode(); } @@ -219,7 +206,6 @@ void VisibilityEnabler2D::_find_nodes(Node *p_node) { } if (add) { - p_node->connect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &VisibilityEnabler2D::_node_removed), varray(p_node), CONNECT_ONESHOT); nodes[p_node] = meta; _change_node_state(p_node, false); @@ -227,42 +213,52 @@ void VisibilityEnabler2D::_find_nodes(Node *p_node) { for (int i = 0; i < p_node->get_child_count(); i++) { Node *c = p_node->get_child(i); - if (c->get_filename() != String()) + if (c->get_filename() != String()) { continue; //skip, instance + } _find_nodes(c); } } void VisibilityEnabler2D::_notification(int p_what) { - if (p_what == NOTIFICATION_ENTER_TREE) { - - if (Engine::get_singleton()->is_editor_hint()) + if (Engine::get_singleton()->is_editor_hint()) { return; + } Node *from = this; //find where current scene starts - while (from->get_parent() && from->get_filename() == String()) + while (from->get_parent() && from->get_filename() == String()) { from = from->get_parent(); + } _find_nodes(from); - if (enabler[ENABLER_PARENT_PHYSICS_PROCESS] && get_parent()) - get_parent()->set_physics_process(false); - if (enabler[ENABLER_PARENT_PROCESS] && get_parent()) - get_parent()->set_process(false); + // We need to defer the call of set_process and set_physics_process, + // otherwise they are overwritten inside NOTIFICATION_READY. + // We can't use call_deferred, because it happens after a physics frame. + // The ready signal works as it's emitted immediately after NOTIFICATION_READY. + + if (enabler[ENABLER_PARENT_PHYSICS_PROCESS] && get_parent()) { + get_parent()->connect(SceneStringNames::get_singleton()->ready, + callable_mp(get_parent(), &Node::set_physics_process), varray(false), CONNECT_ONESHOT); + } + if (enabler[ENABLER_PARENT_PROCESS] && get_parent()) { + get_parent()->connect(SceneStringNames::get_singleton()->ready, + callable_mp(get_parent(), &Node::set_process), varray(false), CONNECT_ONESHOT); + } } if (p_what == NOTIFICATION_EXIT_TREE) { - - if (Engine::get_singleton()->is_editor_hint()) + if (Engine::get_singleton()->is_editor_hint()) { return; + } for (Map<Node *, Variant>::Element *E = nodes.front(); E; E = E->next()) { - - if (!visible) + if (!visible) { _change_node_state(E->key(), true); + } E->key()->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &VisibilityEnabler2D::_node_removed)); } @@ -271,13 +267,11 @@ void VisibilityEnabler2D::_notification(int p_what) { } void VisibilityEnabler2D::_change_node_state(Node *p_node, bool p_enabled) { - ERR_FAIL_COND(!nodes.has(p_node)); if (enabler[ENABLER_FREEZE_BODIES]) { RigidBody2D *rb = Object::cast_to<RigidBody2D>(p_node); if (rb) { - rb->set_sleeping(!p_enabled); } } @@ -286,7 +280,6 @@ void VisibilityEnabler2D::_change_node_state(Node *p_node, bool p_enabled) { AnimationPlayer *ap = Object::cast_to<AnimationPlayer>(p_node); if (ap) { - ap->set_active(p_enabled); } } @@ -295,11 +288,11 @@ void VisibilityEnabler2D::_change_node_state(Node *p_node, bool p_enabled) { AnimatedSprite2D *as = Object::cast_to<AnimatedSprite2D>(p_node); if (as) { - - if (p_enabled) + if (p_enabled) { as->play(); - else + } else { as->stop(); + } } } @@ -307,16 +300,15 @@ void VisibilityEnabler2D::_change_node_state(Node *p_node, bool p_enabled) { GPUParticles2D *ps = Object::cast_to<GPUParticles2D>(p_node); if (ps) { - ps->set_emitting(p_enabled); } } } void VisibilityEnabler2D::_node_removed(Node *p_node) { - - if (!visible) + if (!visible) { _change_node_state(p_node, true); + } nodes.erase(p_node); } @@ -330,7 +322,6 @@ String VisibilityEnabler2D::get_configuration_warning() const { } void VisibilityEnabler2D::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_enabler", "enabler", "enabled"), &VisibilityEnabler2D::set_enabler); ClassDB::bind_method(D_METHOD("is_enabler_enabled", "enabler"), &VisibilityEnabler2D::is_enabler_enabled); ClassDB::bind_method(D_METHOD("_node_removed"), &VisibilityEnabler2D::_node_removed); @@ -352,20 +343,19 @@ void VisibilityEnabler2D::_bind_methods() { } void VisibilityEnabler2D::set_enabler(Enabler p_enabler, bool p_enable) { - ERR_FAIL_INDEX(p_enabler, ENABLER_MAX); enabler[p_enabler] = p_enable; } -bool VisibilityEnabler2D::is_enabler_enabled(Enabler p_enabler) const { +bool VisibilityEnabler2D::is_enabler_enabled(Enabler p_enabler) const { ERR_FAIL_INDEX_V(p_enabler, ENABLER_MAX, false); return enabler[p_enabler]; } VisibilityEnabler2D::VisibilityEnabler2D() { - - for (int i = 0; i < ENABLER_MAX; i++) + for (int i = 0; i < ENABLER_MAX; i++) { enabler[i] = true; + } enabler[ENABLER_PARENT_PROCESS] = false; enabler[ENABLER_PARENT_PHYSICS_PROCESS] = false; |