2d Parallax system broken

Godot Version

4.2.1

Question

Hello everyone! I am a beginner learner and for a while now I’ve been stuck on the Godot Parallax system (ParallaxBackground and ParallaxLayer). I have watched many tutorials on YouTube, but haven’t seen anyone end up with the same problem as mine. I hope to get some insights and understand what I am doing wrong.

My goal is to get a simple parallax effect where every layer moves at a different speed like in most 2d platformers.

I have a player node with a basic x and y movement script and a Camera2d node as a child of the player. I’ve created ParallaxBackground as a child of the main scene, added several ParallaxLayers with sprites attached to them, and changed the values of the Motion scale accordingly as it says in the documentation (as well as in many tutorials that I’ve found). Did everything as per instructions.

Now my problem is this: When I run the project, all of the sprites of the ParallaxLayers with assigned motion scale values (e.g. 0.2, 0.5) change the location on the screen even before I start moving the Player. Even though the parallax is working, the positions of the sprites are stretched to the right of the initial camera position and it completely messes up the composition of the level. I should also add that my level does not have an infinite scroll. It’s just a simple platformer.

I’ve observed that if I put my player (together with the camera attached to it) right at the 0, 0 position in the scene window, my ParallaxLayers seem to be in the initial positions. However, if I move the player somewhere else, the ParallaxLayers get a noticeable offset. I’ve tried this in Godot 3 and the problem persists… I guess it might a Camera2D issue.

Would appreciate any solutions…

The parallax effect follows the camera position. If you need to start at a specific offset you may need to modify the ParallaxBackground.scroll_base_offset property accounting for your camera position.

Yes, I want the parallax effect to follow the camera position at a specified speed for each ParallaxLayer and do nothing else apart from that. However, the parallax effect also offsets every single one of the ParallaxLayers when you run the project if the initial camera position is not 0, 0 (e.g. you have your player in the middle of your level scene) so all of your work in a scene editor becomes useless. So I don’t want this offset and there shouldn’t be any offset to begin with if it’s not specified in the inspector, and in the inspector, the offset values are 0.

I personally found it simpler to just implement my own parallax

structure:
parallax parent

  • sky
  • parallax back
    – rear texture
    – middle texture
    – front texture
  • parallax middle
    – ||
  • parallax front
    – ||

now every frame get the x distance of player movement (dist = player_position.x-last_frame_player_position.x) and call a function in parallax parent with that value

This function does following:

  1. move every parllax layer by its multiplier value (0.75, 0.4, 0.1) times the input x
  2. for every parallax layer check the x position:
    -if layer.position.x > layertexture.size.x: layer.position.x -= layertexture.size.x
    -elif layer.position.x < -layertexture.size.x: layer.position.x += layertexture.size.x

make sure the textures are horizontally repeating and dont forget to factor in texture/nodescaling if you are doing it :wink:
This implementation gives you a lot more control over the parallax layers and lets you implement little happenings into the background for example

1 Like

Thanks for the suggestion! I am thinking of doing that as well.

Also, I’ve found that this issue might be a persistent bug inside Godot.

More info on the problem and solution here

Another solution here here