How can I create parallax background without showing godot's grey background?

Godot Version

4.3

Question

I want the main menu background to move around when I move my mouse so that user can see more of the background if they move the cursor to the left, top, bottom or right. The background image is a bit larger than the game’s viewport.

The way I’m handling it now is resulting in the game showing more than the height and width of my background image is, showing godot’s grey background etc. There’s seems to be no limit.

How can I do this better to achieve what I want and only allow the user to see the whole background but not go beyond it? I’m guessing maybe move the background image itself, instead of the center of viewport? Here’s my code:

@onready var node = $Control
var center: Vector2

func _ready():
center = Vector2(get_viewport_rect().size.x/2, get_viewport_rect().size.y/2)

func _process(_delta):

var tween = node.create_tween()
var offset = center - get_global_mouse_position() * 0.1

tween.tween_property(node,“position”,offset,1.0)

Use a Camera2D with camera limits ?

Take a look at the parallax tutorial and see if it can answer some of your problems: 2D Parallax — Godot Engine (stable) documentation in English

I have the exact same thing in my project, I’ll take a look but on top of my head I’m pretty sure I used camera limits like francois said

Found it! So this is what I tried initially (in C#, it shouldn’t be too different in GDScript):

Vector2 BackgroundImageSize = new Vector2(2100, 1200); // full image resolution

Camera.LimitTop = 0;
Camera.LimitLeft = 0;
Camera.LimitRight = (int)BackgroundImageSize.X;
Camera.LimitBottom = (int)BackgroundImageSize.Y;

But I found out that camera limits are only “visual”, they restrict what you see but they don’t restrict camera position. Meaning if I move my mouse to the left and hit the left limit, the image stays still but the camera continues drifting left. Then when I move right, there is a noticeable delay because the camera is somewhere off-screen, and it has to come back first before it can visibly move to the right. (relevant GitHub issue here: Camera2D limits don't clamp camera position · Issue #62441 · godotengine/godot · GitHub)
I fixed this by clamping the position of the camera instead of using limits, like this:

Vector2 BackgroundImageSize = new Vector2(2100, 1200); // full image resolution

Vector2 viewport = GetViewport().GetVisibleRect().Size;
x_min = viewport.X/2;
x_max = BackgroundImageSize.X/2;
y_min = viewport.Y/2;
y_max = BackgroundImageSize.Y/2;
void SetCameraPosition(float speed)
{
	Camera.Position = Camera.Position.Lerp(GetGlobalMousePosition(), speed);

	Camera.Position = new Vector2(
		Math.Clamp(Camera.Position.X, x_min, x_max),
		Math.Clamp(Camera.Position.Y, y_min, y_max)
	);
}

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.