Skip to content

Commit

Permalink
reverted compatibility-breaking changes and added usability-improving…
Browse files Browse the repository at this point in the history
… properties.
  • Loading branch information
Lazy-Rabbit-2001 committed Jan 12, 2025
1 parent 64942ca commit 908a392
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 16 deletions.
11 changes: 11 additions & 0 deletions doc/classes/Camera2D.xml
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,9 @@
<member name="editor_draw_limits" type="bool" setter="set_limit_drawing_enabled" getter="is_limit_drawing_enabled" default="false">
If [code]true[/code], draws the camera's limits rectangle in the editor.
</member>
<member name="editor_draw_limits_color" type="Color" setter="set_limit_drawing_color" getter="get_limit_drawing_color" default="Color(1, 1, 0.25, 0.63)">
If [code]true[/code], draws the camera's limits rectangle in the editor.
</member>
<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>
Expand All @@ -145,6 +148,11 @@
<member name="limit_left" type="int" setter="set_limit" getter="get_limit" default="-10000000">
Left scroll limit in pixels. The camera stops moving when reaching this value, but [member offset] can push the view past the limit.
</member>
<member name="limit_rect_to_viewport" type="Callable" setter="" getter="" default="Callable()">
A tool button that snaps the limits to the viewport.
In the editor, pressing the button will make [member limit_left] and [member limit_top] become the global position of the camera, and [member limit_right] and [member limit_bottom] become the global position plus the size of the viewport.
[b]Readonly:[/b] Since this is a tool button, it is read-only and trying to set the value of this property will trigger an error.
</member>
<member name="limit_right" type="int" setter="set_limit" getter="get_limit" default="10000000">
Right scroll limit in pixels. The camera stops moving when reaching this value, but [member offset] can push the view past the limit.
</member>
Expand All @@ -156,6 +164,9 @@
<member name="limit_top" type="int" setter="set_limit" getter="get_limit" default="-10000000">
Top scroll limit in pixels. The camera stops moving when reaching this value, but [member offset] can push the view past the limit.
</member>
<member name="limit_unlimited" type="bool" setter="set_limit_unlimited" getter="is_limit_unlimited" default="true">
If [code]true[/code], the camera focus can go anywhere without limits. In this case, the four [code]limit_*[/code] properties will not work.
</member>
<member name="offset" type="Vector2" setter="set_offset" getter="get_offset" default="Vector2(0, 0)">
The camera's relative offset. Useful for looking around or camera shake animations. The offsetted camera can go past the limits defined in [member limit_top], [member limit_bottom], [member limit_left] and [member limit_right].
</member>
Expand Down
86 changes: 70 additions & 16 deletions scene/2d/camera_2d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,19 +48,26 @@ void Camera2D::_edit_set_state(const Dictionary &p_state) {
}

void Camera2D::_edit_set_rect(const Rect2 &p_rect) {
ERR_FAIL_COND(!limit_unlimited && !_edit_use_rect());
Rect2 rect = p_rect;
Vector2 scl = get_global_scale().abs();
rect.size *= scl;
rect.position = (rect.position + get_global_position()) * scl;
_set_limit_rect(rect);
}
#endif // TOOLS_ENABLED

#ifdef DEBUG_ENABLED
Rect2 Camera2D::_edit_get_rect() const {
Rect2 rect = _get_limit_rect();
Vector2 scl = get_global_scale().abs();
rect.size /= scl;
rect.position = (rect.position - get_global_position()) / scl;
return rect;
}

bool Camera2D::_edit_use_rect() const {
return true;
return !limit_unlimited;
}
#endif // DEBUG_ENABLED

Expand Down Expand Up @@ -200,7 +207,7 @@ Transform2D Camera2D::get_camera_transform() {
Point2 screen_offset = (anchor_mode == ANCHOR_MODE_DRAG_CENTER ? (screen_size * 0.5 * zoom_scale) : Point2());
Rect2 screen_rect(-screen_offset + camera_pos, screen_size * zoom_scale);

if (limit_smoothing_enabled) {
if (limit_smoothing_enabled && !limit_unlimited) {
if (screen_rect.position.x < limit[SIDE_LEFT]) {
camera_pos.x -= screen_rect.position.x - limit[SIDE_LEFT];
}
Expand Down Expand Up @@ -253,7 +260,7 @@ Transform2D Camera2D::get_camera_transform() {

Rect2 screen_rect(-screen_offset + ret_camera_pos, screen_size * zoom_scale);

if (!position_smoothing_enabled || !limit_smoothing_enabled) {
if ((!position_smoothing_enabled || !limit_smoothing_enabled) && !limit_unlimited) {
if (screen_rect.position.x < limit[SIDE_LEFT]) {
screen_rect.position.x = limit[SIDE_LEFT];
}
Expand Down Expand Up @@ -426,8 +433,7 @@ void Camera2D::_notification(int p_what) {
}
}

if (limit_drawing_enabled) {
Color limit_drawing_color(1, 1, 0.25, 0.63);
if (limit_drawing_enabled && !limit_unlimited) {
real_t limit_drawing_width = -1;
if (is_current()) {
limit_drawing_width = 3;
Expand Down Expand Up @@ -512,6 +518,16 @@ bool Camera2D::is_ignoring_rotation() const {
return ignore_rotation;
}

void Camera2D::set_limit_unlimited(bool p_limit_unlimited) {
limit_unlimited = p_limit_unlimited;
_update_scroll();
notify_property_list_changed();
}

bool Camera2D::is_limit_unlimited() const {
return limit_unlimited;
}

void Camera2D::set_process_callback(Camera2DProcessCallback p_mode) {
if (process_callback == p_mode) {
return;
Expand Down Expand Up @@ -577,19 +593,25 @@ void Camera2D::_update_process_internal_for_smoothing() {
}

void Camera2D::_set_limit_rect(const Rect2 &p_limit_rect) {
Rect2 limit_rect = p_limit_rect;
limit_rect.position -= get_global_position();
Point2 limit_rect_end = limit_rect.get_end();
limit[SIDE_LEFT] = limit_rect.position.x;
limit[SIDE_TOP] = limit_rect.position.y;
limit[SIDE_RIGHT] = limit_rect_end.x;
limit[SIDE_BOTTOM] = limit_rect_end.y;
Point2 limit_rect_end = p_limit_rect.get_end();
set_limit(SIDE_LEFT, p_limit_rect.position.x);
set_limit(SIDE_TOP, p_limit_rect.position.y);
set_limit(SIDE_RIGHT, limit_rect_end.x);
set_limit(SIDE_BOTTOM, limit_rect_end.y);
}

Rect2 Camera2D::_get_limit_rect() const {
return Rect2(limit[SIDE_LEFT], limit[SIDE_TOP], limit[SIDE_RIGHT] - limit[SIDE_LEFT], limit[SIDE_BOTTOM] - limit[SIDE_TOP]);
}

void Camera2D::_set_limit_rect_to_viewport() {
Point2 origin = get_global_position();
set_limit(SIDE_LEFT, origin.x);
set_limit(SIDE_TOP, origin.y);
set_limit(SIDE_RIGHT, origin.x + float(GLOBAL_GET("display/window/size/viewport_width")));
set_limit(SIDE_BOTTOM, origin.y + float(GLOBAL_GET("display/window/size/viewport_height")));
}

void Camera2D::make_current() {
ERR_FAIL_COND(!enabled || !is_inside_tree());
get_tree()->call_group(group_name, "_make_current", this);
Expand Down Expand Up @@ -639,6 +661,14 @@ int Camera2D::get_limit(Side p_side) const {
return limit[p_side];
}

void Camera2D::set_limit_rect_to_viewport(const Callable &p_limit_rect_to_viewport) {
limit_rect_to_viewport = callable_mp(this, &Camera2D::_set_limit_rect_to_viewport);
}

Callable Camera2D::get_limit_rect_to_viewport() const {
return limit_rect_to_viewport;
}

void Camera2D::set_limit_smoothing_enabled(bool enable) {
limit_smoothing_enabled = enable;
_update_scroll();
Expand Down Expand Up @@ -858,7 +888,18 @@ bool Camera2D::is_margin_drawing_enabled() const {
return margin_drawing_enabled;
}

void Camera2D::set_limit_drawing_color(const Color &p_color) {
limit_drawing_color = p_color;
}

Color Camera2D::get_limit_drawing_color() const {
return limit_drawing_color;
}

void Camera2D::_validate_property(PropertyInfo &p_property) const {
if (limit_unlimited && (p_property.name == "limit_rect_to_viewport" || p_property.name == "limit_smoothed" || p_property.name == "limit_left" || p_property.name == "limit_top" || p_property.name == "limit_right" || p_property.name == "limit_bottom")) {
p_property.usage = PROPERTY_USAGE_NO_EDITOR;
}
if (!position_smoothing_enabled && p_property.name == "position_smoothing_speed") {
p_property.usage = PROPERTY_USAGE_NO_EDITOR;
}
Expand Down Expand Up @@ -889,9 +930,15 @@ void Camera2D::_bind_methods() {
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_unlimited", "limit_unlimited"), &Camera2D::set_limit_unlimited);
ClassDB::bind_method(D_METHOD("is_limit_unlimited"), &Camera2D::is_limit_unlimited);

ClassDB::bind_method(D_METHOD("set_limit", "margin", "limit"), &Camera2D::set_limit);
ClassDB::bind_method(D_METHOD("get_limit", "margin"), &Camera2D::get_limit);

ClassDB::bind_method(D_METHOD("set_limit_rect_to_viewport", "limit_rect_to_viewport"), &Camera2D::set_limit_rect_to_viewport);
ClassDB::bind_method(D_METHOD("get_limit_rect_to_viewport"), &Camera2D::get_limit_rect_to_viewport);

ClassDB::bind_method(D_METHOD("set_limit_smoothing_enabled", "limit_smoothing_enabled"), &Camera2D::set_limit_smoothing_enabled);
ClassDB::bind_method(D_METHOD("is_limit_smoothing_enabled"), &Camera2D::is_limit_smoothing_enabled);

Expand Down Expand Up @@ -946,6 +993,9 @@ void Camera2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_margin_drawing_enabled", "margin_drawing_enabled"), &Camera2D::set_margin_drawing_enabled);
ClassDB::bind_method(D_METHOD("is_margin_drawing_enabled"), &Camera2D::is_margin_drawing_enabled);

ClassDB::bind_method(D_METHOD("set_limit_drawing_color", "limit_drawing_color"), &Camera2D::set_limit_drawing_color);
ClassDB::bind_method(D_METHOD("get_limit_drawing_color"), &Camera2D::get_limit_drawing_color);

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 Top Left,Drag Center"), "set_anchor_mode", "get_anchor_mode");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "ignore_rotation"), "set_ignore_rotation", "is_ignoring_rotation");
Expand All @@ -955,10 +1005,12 @@ void Camera2D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "process_callback", PROPERTY_HINT_ENUM, "Physics,Idle"), "set_process_callback", "get_process_callback");

ADD_GROUP("Limit", "limit_");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "limit_unlimited"), "set_limit_unlimited", "is_limit_unlimited");
ADD_PROPERTYI(PropertyInfo(Variant::INT, "limit_left", PROPERTY_HINT_NONE, "suffix:px"), "set_limit", "get_limit", SIDE_LEFT);
ADD_PROPERTYI(PropertyInfo(Variant::INT, "limit_top", PROPERTY_HINT_NONE, "suffix:px"), "set_limit", "get_limit", SIDE_TOP);
ADD_PROPERTYI(PropertyInfo(Variant::INT, "limit_right", PROPERTY_HINT_NONE, "suffix:px"), "set_limit", "get_limit", SIDE_RIGHT);
ADD_PROPERTYI(PropertyInfo(Variant::INT, "limit_bottom", PROPERTY_HINT_NONE, "suffix:px"), "set_limit", "get_limit", SIDE_BOTTOM);
ADD_PROPERTY(PropertyInfo(Variant::CALLABLE, "limit_rect_to_viewport", PROPERTY_HINT_TOOL_BUTTON, "Snap Limit to Viewport"), "", "get_limit_rect_to_viewport");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "limit_smoothed"), "set_limit_smoothing_enabled", "is_limit_smoothing_enabled");

ADD_GROUP("Position Smoothing", "position_smoothing_");
Expand All @@ -982,6 +1034,7 @@ void Camera2D::_bind_methods() {
ADD_GROUP("Editor", "editor_");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "editor_draw_screen"), "set_screen_drawing_enabled", "is_screen_drawing_enabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "editor_draw_limits"), "set_limit_drawing_enabled", "is_limit_drawing_enabled");
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "editor_draw_limits_color"), "set_limit_rect_to_viewport", "get_limit_rect_to_viewport");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "editor_draw_drag_margin"), "set_margin_drawing_enabled", "is_margin_drawing_enabled");

BIND_ENUM_CONSTANT(ANCHOR_MODE_FIXED_TOP_LEFT);
Expand All @@ -991,10 +1044,11 @@ void Camera2D::_bind_methods() {
}

Camera2D::Camera2D() {
limit[SIDE_LEFT] = 0;
limit[SIDE_TOP] = 0;
limit[SIDE_RIGHT] = GLOBAL_GET("display/window/size/viewport_width");
limit[SIDE_BOTTOM] = GLOBAL_GET("display/window/size/viewport_height");
limit[SIDE_LEFT] = -10000000;
limit[SIDE_TOP] = -10000000;
limit[SIDE_RIGHT] = 10000000;
limit[SIDE_BOTTOM] = 10000000;
limit_rect_to_viewport = callable_mp(this, &Camera2D::_set_limit_rect_to_viewport);

drag_margin[SIDE_LEFT] = 0.2;
drag_margin[SIDE_TOP] = 0.2;
Expand Down
13 changes: 13 additions & 0 deletions scene/2d/camera_2d.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,10 @@ class Camera2D : public Node2D {
real_t rotation_smoothing_speed = 5.0;
bool rotation_smoothing_enabled = false;

bool limit_unlimited = true;
int limit[4];
bool limit_smoothing_enabled = false;
Callable limit_rect_to_viewport;

real_t drag_margin[4];
bool drag_horizontal_enabled = false;
Expand All @@ -101,10 +103,12 @@ class Camera2D : public Node2D {

void _set_limit_rect(const Rect2 &p_limit_rect);
Rect2 _get_limit_rect() const;
void _set_limit_rect_to_viewport();

bool screen_drawing_enabled = true;
bool limit_drawing_enabled = false;
bool margin_drawing_enabled = false;
Color limit_drawing_color = Color(1, 1, 0.25, 0.63);

Camera2DProcessCallback process_callback = CAMERA2D_PROCESS_IDLE;

Expand Down Expand Up @@ -151,9 +155,15 @@ class Camera2D : public Node2D {
void set_ignore_rotation(bool p_ignore);
bool is_ignoring_rotation() const;

void set_limit_unlimited(bool p_limit_unlimited);
bool is_limit_unlimited() const;

void set_limit(Side p_side, int p_limit);
int get_limit(Side p_side) const;

void set_limit_rect_to_viewport(const Callable &p_limit_rect_to_viewport);
Callable get_limit_rect_to_viewport() const;

void set_limit_smoothing_enabled(bool enable);
bool is_limit_smoothing_enabled() const;

Expand Down Expand Up @@ -216,6 +226,9 @@ class Camera2D : public Node2D {
void set_margin_drawing_enabled(bool enable);
bool is_margin_drawing_enabled() const;

void set_limit_drawing_color(const Color &p_color);
Color get_limit_drawing_color() const;

Camera2D();
};

Expand Down

0 comments on commit 908a392

Please sign in to comment.