Skip to content

Commit 51080b2

Browse files
committed
Merge pull request godotengine#106180 from ogapo/2d-camera-limits-fix
Improved Camera2D limits handling when limits are smaller than screen rect
2 parents d82d9c3 + 5afb64e commit 51080b2

File tree

1 file changed

+34
-18
lines changed

1 file changed

+34
-18
lines changed

scene/2d/camera_2d.cpp

Lines changed: 34 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -219,20 +219,28 @@ Transform2D Camera2D::get_camera_transform() {
219219
Rect2 screen_rect(-screen_offset + camera_pos, screen_size * zoom_scale);
220220

221221
if (limit_enabled && limit_smoothing_enabled) {
222-
if (screen_rect.position.x < limit[SIDE_LEFT]) {
222+
// Apply horizontal limiting.
223+
if (screen_rect.size.x > limit[SIDE_RIGHT] - limit[SIDE_LEFT]) {
224+
// Split the limit difference horizontally.
225+
camera_pos.x -= screen_rect.position.x + (screen_rect.size.x - limit[SIDE_RIGHT] - limit[SIDE_LEFT]) / 2;
226+
} else if (screen_rect.position.x < limit[SIDE_LEFT]) {
227+
// Only apply left limit.
223228
camera_pos.x -= screen_rect.position.x - limit[SIDE_LEFT];
224-
}
225-
226-
if (screen_rect.position.x + screen_rect.size.x > limit[SIDE_RIGHT]) {
229+
} else if (screen_rect.position.x + screen_rect.size.x > limit[SIDE_RIGHT]) {
230+
// Only apply the right limit.
227231
camera_pos.x -= screen_rect.position.x + screen_rect.size.x - limit[SIDE_RIGHT];
228232
}
229233

230-
if (screen_rect.position.y + screen_rect.size.y > limit[SIDE_BOTTOM]) {
231-
camera_pos.y -= screen_rect.position.y + screen_rect.size.y - limit[SIDE_BOTTOM];
232-
}
233-
234-
if (screen_rect.position.y < limit[SIDE_TOP]) {
234+
// Apply vertical limiting.
235+
if (screen_rect.size.y > limit[SIDE_BOTTOM] - limit[SIDE_TOP]) {
236+
// Split the limit difference vertically.
237+
camera_pos.y -= screen_rect.position.y + (screen_rect.size.y - limit[SIDE_BOTTOM] - limit[SIDE_TOP]) / 2;
238+
} else if (screen_rect.position.y < limit[SIDE_TOP]) {
239+
// Only apply the top limit.
235240
camera_pos.y -= screen_rect.position.y - limit[SIDE_TOP];
241+
} else if (screen_rect.position.y + screen_rect.size.y > limit[SIDE_BOTTOM]) {
242+
// Only apply the bottom limit.
243+
camera_pos.y -= screen_rect.position.y + screen_rect.size.y - limit[SIDE_BOTTOM];
236244
}
237245
}
238246

@@ -273,20 +281,28 @@ Transform2D Camera2D::get_camera_transform() {
273281

274282
if (limit_enabled && (!position_smoothing_enabled || !limit_smoothing_enabled)) {
275283
Point2 bottom_right_corner = Point2(screen_rect.position + 2.0 * (camera_pos - screen_rect.position));
276-
if (screen_rect.position.x < limit[SIDE_LEFT]) {
284+
// Apply horizontal limiting.
285+
if (bottom_right_corner.x - screen_rect.position.x > limit[SIDE_RIGHT] - limit[SIDE_LEFT]) {
286+
// Split the difference horizontally (center it).
287+
screen_rect.position.x = (limit[SIDE_LEFT] + limit[SIDE_RIGHT] - (bottom_right_corner.x - screen_rect.position.x)) / 2;
288+
} else if (screen_rect.position.x < limit[SIDE_LEFT]) {
289+
// Only apply left limit.
277290
screen_rect.position.x = limit[SIDE_LEFT];
278-
}
279-
280-
if (bottom_right_corner.x > limit[SIDE_RIGHT]) {
291+
} else if (bottom_right_corner.x > limit[SIDE_RIGHT]) {
292+
// Only apply right limit.
281293
screen_rect.position.x = limit[SIDE_RIGHT] - (bottom_right_corner.x - screen_rect.position.x);
282294
}
283295

284-
if (bottom_right_corner.y > limit[SIDE_BOTTOM]) {
285-
screen_rect.position.y = limit[SIDE_BOTTOM] - (bottom_right_corner.y - screen_rect.position.y);
286-
}
287-
288-
if (screen_rect.position.y < limit[SIDE_TOP]) {
296+
// Apply vertical limiting.
297+
if (bottom_right_corner.y - screen_rect.position.y > limit[SIDE_BOTTOM] - limit[SIDE_TOP]) {
298+
// Split the limit difference vertically.
299+
screen_rect.position.y = (limit[SIDE_TOP] + limit[SIDE_BOTTOM] - (bottom_right_corner.y - screen_rect.position.y)) / 2;
300+
} else if (screen_rect.position.y < limit[SIDE_TOP]) {
301+
// Only apply the top limit.
289302
screen_rect.position.y = limit[SIDE_TOP];
303+
} else if (bottom_right_corner.y > limit[SIDE_BOTTOM]) {
304+
// Only apply the bottom limit.
305+
screen_rect.position.y = limit[SIDE_BOTTOM] - (bottom_right_corner.y - screen_rect.position.y);
290306
}
291307
}
292308

0 commit comments

Comments
 (0)