diff --git a/scene/2d/camera_2d.cpp b/scene/2d/camera_2d.cpp index 96516de2fe4..b2bb56cf70e 100644 --- a/scene/2d/camera_2d.cpp +++ b/scene/2d/camera_2d.cpp @@ -219,20 +219,28 @@ Transform2D Camera2D::get_camera_transform() { Rect2 screen_rect(-screen_offset + camera_pos, screen_size * zoom_scale); if (limit_enabled && limit_smoothing_enabled) { - if (screen_rect.position.x < limit[SIDE_LEFT]) { + // Apply horizontal limiting. + if (screen_rect.size.x > limit[SIDE_RIGHT] - limit[SIDE_LEFT]) { + // Split the limit difference horizontally. + camera_pos.x -= screen_rect.position.x + (screen_rect.size.x - limit[SIDE_RIGHT] - limit[SIDE_LEFT]) / 2; + } else if (screen_rect.position.x < limit[SIDE_LEFT]) { + // Only apply left limit. camera_pos.x -= screen_rect.position.x - limit[SIDE_LEFT]; - } - - if (screen_rect.position.x + screen_rect.size.x > limit[SIDE_RIGHT]) { + } else if (screen_rect.position.x + screen_rect.size.x > limit[SIDE_RIGHT]) { + // Only apply the right limit. camera_pos.x -= screen_rect.position.x + screen_rect.size.x - limit[SIDE_RIGHT]; } - if (screen_rect.position.y + screen_rect.size.y > limit[SIDE_BOTTOM]) { - camera_pos.y -= screen_rect.position.y + screen_rect.size.y - limit[SIDE_BOTTOM]; - } - - if (screen_rect.position.y < limit[SIDE_TOP]) { + // Apply vertical limiting. + if (screen_rect.size.y > limit[SIDE_BOTTOM] - limit[SIDE_TOP]) { + // Split the limit difference vertically. + camera_pos.y -= screen_rect.position.y + (screen_rect.size.y - limit[SIDE_BOTTOM] - limit[SIDE_TOP]) / 2; + } else if (screen_rect.position.y < limit[SIDE_TOP]) { + // Only apply the top limit. camera_pos.y -= screen_rect.position.y - limit[SIDE_TOP]; + } else if (screen_rect.position.y + screen_rect.size.y > limit[SIDE_BOTTOM]) { + // Only apply the bottom limit. + camera_pos.y -= screen_rect.position.y + screen_rect.size.y - limit[SIDE_BOTTOM]; } } @@ -273,20 +281,28 @@ Transform2D Camera2D::get_camera_transform() { if (limit_enabled && (!position_smoothing_enabled || !limit_smoothing_enabled)) { Point2 bottom_right_corner = Point2(screen_rect.position + 2.0 * (camera_pos - screen_rect.position)); - if (screen_rect.position.x < limit[SIDE_LEFT]) { + // Apply horizontal limiting. + if (bottom_right_corner.x - screen_rect.position.x > limit[SIDE_RIGHT] - limit[SIDE_LEFT]) { + // Split the difference horizontally (center it). + screen_rect.position.x = (limit[SIDE_LEFT] + limit[SIDE_RIGHT] - (bottom_right_corner.x - screen_rect.position.x)) / 2; + } else if (screen_rect.position.x < limit[SIDE_LEFT]) { + // Only apply left limit. screen_rect.position.x = limit[SIDE_LEFT]; - } - - if (bottom_right_corner.x > limit[SIDE_RIGHT]) { + } else if (bottom_right_corner.x > limit[SIDE_RIGHT]) { + // Only apply right limit. screen_rect.position.x = limit[SIDE_RIGHT] - (bottom_right_corner.x - screen_rect.position.x); } - if (bottom_right_corner.y > limit[SIDE_BOTTOM]) { - screen_rect.position.y = limit[SIDE_BOTTOM] - (bottom_right_corner.y - screen_rect.position.y); - } - - if (screen_rect.position.y < limit[SIDE_TOP]) { + // Apply vertical limiting. + if (bottom_right_corner.y - screen_rect.position.y > limit[SIDE_BOTTOM] - limit[SIDE_TOP]) { + // Split the limit difference vertically. + screen_rect.position.y = (limit[SIDE_TOP] + limit[SIDE_BOTTOM] - (bottom_right_corner.y - screen_rect.position.y)) / 2; + } else if (screen_rect.position.y < limit[SIDE_TOP]) { + // Only apply the top limit. screen_rect.position.y = limit[SIDE_TOP]; + } else if (bottom_right_corner.y > limit[SIDE_BOTTOM]) { + // Only apply the bottom limit. + screen_rect.position.y = limit[SIDE_BOTTOM] - (bottom_right_corner.y - screen_rect.position.y); } }