diff --git a/doc/classes/Camera2D.xml b/doc/classes/Camera2D.xml index 76e60418e..739ef59a3 100644 --- a/doc/classes/Camera2D.xml +++ b/doc/classes/Camera2D.xml @@ -20,12 +20,6 @@ Aligns the camera to the tracked node. - - - - Removes any [Camera2D] from the ancestor [Viewport]'s internal currently-assigned camera. - - @@ -60,12 +54,6 @@ Returns the specified camera limit. See also [member limit_bottom], [member limit_top], [member limit_left], and [member limit_right]. - - - - Make this the current 2D camera for the scene (viewport and layer), in case there are many cameras in the scene. - - @@ -94,7 +82,7 @@ The Camera2D's anchor point. See [enum AnchorMode] constants. - + If [code]true[/code], the camera is the active camera for the current scene. Only one camera can be current, so setting a different camera [code]current[/code] will disable this one. diff --git a/doc/classes/Viewport.xml b/doc/classes/Viewport.xml index a70e4c43c..432bfb544 100644 --- a/doc/classes/Viewport.xml +++ b/doc/classes/Viewport.xml @@ -35,6 +35,13 @@ Returns the first valid [World2D] for this viewport, searching the [member world_2d] property of itself and any Viewport ancestor. + + + + + Returns the currently active 2D camera. Returns null if there are no active cameras. + + diff --git a/scene/2d/camera_2d.cpp b/scene/2d/camera_2d.cpp index ebc921d87..1c168b549 100644 --- a/scene/2d/camera_2d.cpp +++ b/scene/2d/camera_2d.cpp @@ -256,7 +256,10 @@ void Camera2D::_notification(int p_what) { // it should take over as the current camera, and mark // all other cameras as non current first = true; - _set_current(current); + + if (is_current()) { + viewport->_camera_2d_set(this); + } } break; case NOTIFICATION_EXIT_TREE: { @@ -264,6 +267,7 @@ void Camera2D::_notification(int p_what) { if (is_current()) { if (viewport && viewport_valid) { viewport->set_canvas_transform(Transform2D()); + clear_current(); } } if (viewport && viewport_valid) { @@ -400,18 +404,29 @@ Camera2D::Camera2DProcessMode Camera2D::get_process_mode() const { void Camera2D::_make_current(Object *p_which) { if (p_which == this) { current = true; + if (is_inside_tree()) { + get_viewport()->_camera_2d_set(this); + update(); + } } else { current = false; + if (is_inside_tree()) { + if (get_viewport()->get_camera_2d() == this) { + get_viewport()->_camera_2d_set(nullptr); + } + update(); + } } } -void Camera2D::_set_current(bool p_current) { +void Camera2D::set_current(bool p_current) { if (p_current) { make_current(); + } else { + if (current) { + clear_current(); + } } - - current = p_current; - update(); } bool Camera2D::is_current() const { @@ -419,18 +434,20 @@ bool Camera2D::is_current() const { } void Camera2D::make_current() { - if (!is_inside_tree()) { - current = true; - } else { + if (is_inside_tree()) { get_tree()->call_group_flags(SceneTree::GROUP_CALL_REALTIME, group_name, "_make_current", this); + } else { + current = true; } + _update_scroll(); } void Camera2D::clear_current() { - current = false; if (is_inside_tree()) { get_tree()->call_group_flags(SceneTree::GROUP_CALL_REALTIME, group_name, "_make_current", (Object *)nullptr); + } else { + current = false; } } @@ -649,17 +666,14 @@ void Camera2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_rotating", "rotating"), &Camera2D::set_rotating); ClassDB::bind_method(D_METHOD("is_rotating"), &Camera2D::is_rotating); - ClassDB::bind_method(D_METHOD("make_current"), &Camera2D::make_current); - ClassDB::bind_method(D_METHOD("clear_current"), &Camera2D::clear_current); - ClassDB::bind_method(D_METHOD("_make_current"), &Camera2D::_make_current); - ClassDB::bind_method(D_METHOD("_update_scroll"), &Camera2D::_update_scroll); ClassDB::bind_method(D_METHOD("set_process_mode", "mode"), &Camera2D::set_process_mode); ClassDB::bind_method(D_METHOD("get_process_mode"), &Camera2D::get_process_mode); - ClassDB::bind_method(D_METHOD("_set_current", "current"), &Camera2D::_set_current); + ClassDB::bind_method(D_METHOD("set_current", "current"), &Camera2D::set_current); ClassDB::bind_method(D_METHOD("is_current"), &Camera2D::is_current); + ClassDB::bind_method(D_METHOD("_make_current"), &Camera2D::_make_current); ClassDB::bind_method(D_METHOD("set_limit", "margin", "limit"), &Camera2D::set_limit); ClassDB::bind_method(D_METHOD("get_limit", "margin"), &Camera2D::get_limit); @@ -713,7 +727,7 @@ void Camera2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "offset"), "set_offset", "get_offset"); ADD_PROPERTY(PropertyInfo(Variant::INT, "anchor_mode", PROPERTY_HINT_ENUM, "Fixed TopLeft,Drag Center"), "set_anchor_mode", "get_anchor_mode"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "rotating"), "set_rotating", "is_rotating"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "current"), "_set_current", "is_current"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "current"), "set_current", "is_current"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "zoom"), "set_zoom", "get_zoom"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "custom_viewport", PROPERTY_HINT_RESOURCE_TYPE, "Viewport", 0), "set_custom_viewport", "get_custom_viewport"); ADD_PROPERTY(PropertyInfo(Variant::INT, "process_mode", PROPERTY_HINT_ENUM, "Physics,Idle"), "set_process_mode", "get_process_mode"); diff --git a/scene/2d/camera_2d.h b/scene/2d/camera_2d.h index 1ef1ef325..baff8f2a9 100644 --- a/scene/2d/camera_2d.h +++ b/scene/2d/camera_2d.h @@ -86,7 +86,7 @@ protected: void _setup_viewport(); void _make_current(Object *p_which); - void _set_current(bool p_current); + void set_current(bool p_current); bool screen_drawing_enabled; bool limit_drawing_enabled; diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index 5910898ac..d3116bceb 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -34,6 +34,7 @@ #include "core/os/input.h" #include "core/os/os.h" #include "core/project_settings.h" +#include "scene/2d/camera_2d.h" #include "scene/2d/collision_object_2d.h" #include "scene/2d/listener_2d.h" #include "scene/3d/camera.h" @@ -944,6 +945,10 @@ void Viewport::_camera_set(Camera *p_camera) { #endif } +void Viewport::_camera_2d_set(Camera2D *p_camera_2d) { + camera_2d = p_camera_2d; +} + bool Viewport::_camera_add(Camera *p_camera) { cameras.insert(p_camera); return cameras.size() == 1; @@ -1168,6 +1173,10 @@ Camera *Viewport::get_camera() const { return camera; } +Camera2D *Viewport::get_camera_2d() const { + return camera_2d; +} + void Viewport::enable_camera_override(bool p_enable) { #ifndef _3D_DISABLED if (p_enable == camera_override) { @@ -3266,6 +3275,7 @@ void Viewport::_bind_methods() { ClassDB::bind_method(D_METHOD("is_using_own_world"), &Viewport::is_using_own_world); ClassDB::bind_method(D_METHOD("get_camera"), &Viewport::get_camera); + ClassDB::bind_method(D_METHOD("get_camera_2d"), &Viewport::get_camera_2d); ClassDB::bind_method(D_METHOD("set_as_audio_listener", "enable"), &Viewport::set_as_audio_listener); ClassDB::bind_method(D_METHOD("is_audio_listener"), &Viewport::is_audio_listener); @@ -3436,6 +3446,7 @@ Viewport::Viewport() { parent = nullptr; listener = nullptr; camera = nullptr; + camera_2d = nullptr; override_canvas_transform = false; canvas_layers.insert(NULL); // This eases picking code (interpreted as the canvas of the Viewport) arvr = false; diff --git a/scene/main/viewport.h b/scene/main/viewport.h index 50ff36eaf..33c8c55cb 100644 --- a/scene/main/viewport.h +++ b/scene/main/viewport.h @@ -181,6 +181,7 @@ private: } camera_override; Camera *camera; + Camera2D *camera_2d; Set cameras; Listener2D *listener_2d = nullptr; Set canvas_layers; @@ -406,6 +407,9 @@ private: void _camera_remove(Camera *p_camera); void _camera_make_next_current(Camera *p_exclude); + friend class Camera2D; + void _camera_2d_set(Camera2D *p_camera_2d); + friend class Listener2D; void _listener_2d_set(Listener2D *p_listener); void _listener_2d_remove(Listener2D *p_listener); @@ -430,6 +434,7 @@ protected: public: Listener *get_listener() const; Camera *get_camera() const; + Camera2D *get_camera_2d() const; void enable_camera_override(bool p_enable); bool is_camera_override_enabled() const;