Merge pull request #65698 from KoBeWi/cameraman
Rework how current Camera2D is determined
This commit is contained in:
commit
14a4408e02
5 changed files with 79 additions and 44 deletions
|
@ -55,6 +55,18 @@
|
|||
[b]Note:[/b] The returned value is not the same as [member Node2D.global_position], as it is affected by the drag properties. It is also not the same as the current position if [member position_smoothing_enabled] is [code]true[/code] (see [method get_screen_center_position]).
|
||||
</description>
|
||||
</method>
|
||||
<method name="is_current" qualifiers="const">
|
||||
<return type="bool" />
|
||||
<description>
|
||||
Returns [code]true[/code] if this [Camera2D] is the active camera (see [method Viewport.get_camera_2d]).
|
||||
</description>
|
||||
</method>
|
||||
<method name="make_current">
|
||||
<return type="void" />
|
||||
<description>
|
||||
Forces this [Camera2D] to become the current active one. [member enabled] must be [code]true[/code].
|
||||
</description>
|
||||
</method>
|
||||
<method name="reset_smoothing">
|
||||
<return type="void" />
|
||||
<description>
|
||||
|
@ -83,9 +95,6 @@
|
|||
<member name="anchor_mode" type="int" setter="set_anchor_mode" getter="get_anchor_mode" enum="Camera2D.AnchorMode" default="1">
|
||||
The Camera2D's anchor point. See [enum AnchorMode] constants.
|
||||
</member>
|
||||
<member name="current" type="bool" setter="set_current" getter="is_current" default="false">
|
||||
If [code]true[/code], the camera acts as the active camera for its [Viewport] ancestor. Only one camera can be current in a given viewport, so setting a different camera in the same viewport [code]current[/code] will disable whatever camera was already active in that viewport.
|
||||
</member>
|
||||
<member name="custom_viewport" type="Node" setter="set_custom_viewport" getter="get_custom_viewport">
|
||||
The custom [Viewport] node attached to the [Camera2D]. If [code]null[/code] or not a [Viewport], uses the default viewport instead.
|
||||
</member>
|
||||
|
@ -124,6 +133,10 @@
|
|||
<member name="editor_draw_screen" type="bool" setter="set_screen_drawing_enabled" getter="is_screen_drawing_enabled" default="true">
|
||||
If [code]true[/code], draws the camera's screen rectangle in the editor.
|
||||
</member>
|
||||
<member name="enabled" type="bool" setter="set_enabled" getter="is_enabled" default="true">
|
||||
Controls whether the camera can be active or not. If [code]true[/code], the [Camera2D] will become the main camera when it enters the scene tree and there is no active camera currently (see [method Viewport.get_camera_2d]).
|
||||
When the camera is currently active and [member enabled] is set to [code]false[/code], the next enabled [Camera2D] in the scene tree will become active.
|
||||
</member>
|
||||
<member name="ignore_rotation" type="bool" setter="set_ignore_rotation" getter="is_ignoring_rotation" default="true">
|
||||
If [code]true[/code], the camera's rendered view is not affected by its [member Node2D.rotation] and [member Node2D.global_rotation].
|
||||
</member>
|
||||
|
|
|
@ -50,7 +50,7 @@ void Camera2D::_update_scroll() {
|
|||
return;
|
||||
}
|
||||
|
||||
if (current) {
|
||||
if (is_current()) {
|
||||
ERR_FAIL_COND(custom_viewport && !ObjectDB::get_instance(custom_viewport_id));
|
||||
|
||||
Transform2D xform = get_camera_transform();
|
||||
|
@ -241,10 +241,6 @@ void Camera2D::_notification(int p_what) {
|
|||
viewport = get_viewport();
|
||||
}
|
||||
|
||||
if (is_current()) {
|
||||
viewport->_camera_2d_set(this);
|
||||
}
|
||||
|
||||
canvas = get_canvas();
|
||||
|
||||
RID vp = viewport->get_viewport_rid();
|
||||
|
@ -254,6 +250,10 @@ void Camera2D::_notification(int p_what) {
|
|||
add_to_group(group_name);
|
||||
add_to_group(canvas_group_name);
|
||||
|
||||
if (enabled && !viewport->get_camera_2d()) {
|
||||
make_current();
|
||||
}
|
||||
|
||||
_update_process_callback();
|
||||
first = true;
|
||||
_update_scroll();
|
||||
|
@ -261,11 +261,7 @@ void Camera2D::_notification(int p_what) {
|
|||
|
||||
case NOTIFICATION_EXIT_TREE: {
|
||||
if (is_current()) {
|
||||
if (viewport && !(custom_viewport && !ObjectDB::get_instance(custom_viewport_id))) {
|
||||
viewport->set_canvas_transform(Transform2D());
|
||||
clear_current();
|
||||
current = true;
|
||||
}
|
||||
clear_current();
|
||||
}
|
||||
remove_from_group(group_name);
|
||||
remove_from_group(canvas_group_name);
|
||||
|
@ -397,19 +393,31 @@ void Camera2D::set_process_callback(Camera2DProcessCallback p_mode) {
|
|||
_update_process_callback();
|
||||
}
|
||||
|
||||
void Camera2D::set_enabled(bool p_enabled) {
|
||||
enabled = p_enabled;
|
||||
|
||||
if (enabled && is_inside_tree() && !viewport->get_camera_2d()) {
|
||||
make_current();
|
||||
} else if (!enabled && is_current()) {
|
||||
clear_current();
|
||||
}
|
||||
}
|
||||
|
||||
bool Camera2D::is_enabled() const {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
Camera2D::Camera2DProcessCallback Camera2D::get_process_callback() const {
|
||||
return process_callback;
|
||||
}
|
||||
|
||||
void Camera2D::_make_current(Object *p_which) {
|
||||
if (p_which == this) {
|
||||
current = true;
|
||||
if (is_inside_tree()) {
|
||||
get_viewport()->_camera_2d_set(this);
|
||||
queue_redraw();
|
||||
}
|
||||
} else {
|
||||
current = false;
|
||||
if (is_inside_tree()) {
|
||||
if (get_viewport()->get_camera_2d() == this) {
|
||||
get_viewport()->_camera_2d_set(nullptr);
|
||||
|
@ -419,45 +427,34 @@ void Camera2D::_make_current(Object *p_which) {
|
|||
}
|
||||
}
|
||||
|
||||
void Camera2D::set_current(bool p_current) {
|
||||
if (p_current) {
|
||||
make_current();
|
||||
} else {
|
||||
if (current) {
|
||||
clear_current();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Camera2D::_update_process_internal_for_smoothing() {
|
||||
bool is_not_in_scene_or_editor = !(is_inside_tree() && Engine::get_singleton()->is_editor_hint());
|
||||
bool is_any_smoothing_valid = position_smoothing_speed > 0 || rotation_smoothing_speed > 0;
|
||||
|
||||
bool enabled = is_any_smoothing_valid && is_not_in_scene_or_editor;
|
||||
set_process_internal(enabled);
|
||||
}
|
||||
|
||||
bool Camera2D::is_current() const {
|
||||
return current;
|
||||
bool enable = is_any_smoothing_valid && is_not_in_scene_or_editor;
|
||||
set_process_internal(enable);
|
||||
}
|
||||
|
||||
void Camera2D::make_current() {
|
||||
if (is_inside_tree()) {
|
||||
get_tree()->call_group(group_name, "_make_current", this);
|
||||
} else {
|
||||
current = true;
|
||||
}
|
||||
ERR_FAIL_COND(!enabled || !is_inside_tree());
|
||||
get_tree()->call_group(group_name, "_make_current", this);
|
||||
_update_scroll();
|
||||
}
|
||||
|
||||
void Camera2D::clear_current() {
|
||||
if (is_inside_tree()) {
|
||||
get_tree()->call_group(group_name, "_make_current", (Object *)nullptr);
|
||||
} else {
|
||||
current = false;
|
||||
ERR_FAIL_COND(!is_current());
|
||||
if (viewport && !(custom_viewport && !ObjectDB::get_instance(custom_viewport_id))) {
|
||||
viewport->assign_next_enabled_camera_2d(group_name);
|
||||
}
|
||||
}
|
||||
|
||||
bool Camera2D::is_current() const {
|
||||
if (viewport && !(custom_viewport && !ObjectDB::get_instance(custom_viewport_id))) {
|
||||
return viewport->get_camera_2d() == this;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Camera2D::set_limit(Side p_side, int p_limit) {
|
||||
ERR_FAIL_INDEX((int)p_side, 4);
|
||||
limit[p_side] = p_limit;
|
||||
|
@ -715,7 +712,10 @@ void Camera2D::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("set_process_callback", "mode"), &Camera2D::set_process_callback);
|
||||
ClassDB::bind_method(D_METHOD("get_process_callback"), &Camera2D::get_process_callback);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_current", "current"), &Camera2D::set_current);
|
||||
ClassDB::bind_method(D_METHOD("set_enabled", "enabled"), &Camera2D::set_enabled);
|
||||
ClassDB::bind_method(D_METHOD("is_enabled"), &Camera2D::is_enabled);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("make_current"), &Camera2D::make_current);
|
||||
ClassDB::bind_method(D_METHOD("is_current"), &Camera2D::is_current);
|
||||
ClassDB::bind_method(D_METHOD("_make_current"), &Camera2D::_make_current);
|
||||
|
||||
|
@ -779,7 +779,7 @@ void Camera2D::_bind_methods() {
|
|||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "offset", PROPERTY_HINT_NONE, "suffix:px"), "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, "ignore_rotation"), "set_ignore_rotation", "is_ignoring_rotation");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "current"), "set_current", "is_current");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "enabled"), "set_enabled", "is_enabled");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "zoom", PROPERTY_HINT_LINK), "set_zoom", "get_zoom");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "custom_viewport", PROPERTY_HINT_RESOURCE_TYPE, "Viewport", PROPERTY_USAGE_NONE), "set_custom_viewport", "get_custom_viewport");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "process_callback", PROPERTY_HINT_ENUM, "Physics,Idle"), "set_process_callback", "get_process_callback");
|
||||
|
|
|
@ -64,7 +64,7 @@ protected:
|
|||
Vector2 zoom_scale = Vector2(1, 1);
|
||||
AnchorMode anchor_mode = ANCHOR_MODE_DRAG_CENTER;
|
||||
bool ignore_rotation = true;
|
||||
bool current = false;
|
||||
bool enabled = true;
|
||||
real_t position_smoothing_speed = 5.0;
|
||||
bool follow_smoothing_enabled = false;
|
||||
|
||||
|
@ -88,7 +88,6 @@ protected:
|
|||
void _update_scroll();
|
||||
|
||||
void _make_current(Object *p_which);
|
||||
void set_current(bool p_current);
|
||||
|
||||
void _set_old_smoothing(real_t p_enable);
|
||||
|
||||
|
@ -155,6 +154,9 @@ public:
|
|||
void set_process_callback(Camera2DProcessCallback p_mode);
|
||||
Camera2DProcessCallback get_process_callback() const;
|
||||
|
||||
void set_enabled(bool p_enabled);
|
||||
bool is_enabled() const;
|
||||
|
||||
void make_current();
|
||||
void clear_current();
|
||||
bool is_current() const;
|
||||
|
|
|
@ -1045,6 +1045,25 @@ Transform2D Viewport::get_final_transform() const {
|
|||
return _get_input_pre_xform().affine_inverse() * stretch_transform * global_canvas_transform;
|
||||
}
|
||||
|
||||
void Viewport::assign_next_enabled_camera_2d(const StringName &p_camera_group) {
|
||||
List<Node *> camera_list;
|
||||
get_tree()->get_nodes_in_group(p_camera_group, &camera_list);
|
||||
|
||||
Camera2D *new_camera = nullptr;
|
||||
for (const Node *E : camera_list) {
|
||||
const Camera2D *cam = Object::cast_to<Camera2D>(E);
|
||||
if (cam->is_enabled()) {
|
||||
new_camera = const_cast<Camera2D *>(cam);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
_camera_2d_set(new_camera);
|
||||
if (!camera_2d) {
|
||||
set_canvas_transform(Transform2D());
|
||||
}
|
||||
}
|
||||
|
||||
void Viewport::_update_canvas_items(Node *p_node) {
|
||||
if (p_node != this) {
|
||||
Window *w = Object::cast_to<Window>(p_node);
|
||||
|
|
|
@ -511,6 +511,7 @@ public:
|
|||
Transform2D get_global_canvas_transform() const;
|
||||
|
||||
Transform2D get_final_transform() const;
|
||||
void assign_next_enabled_camera_2d(const StringName &p_camera_group);
|
||||
|
||||
void gui_set_root_order_dirty();
|
||||
|
||||
|
|
Loading…
Reference in a new issue