Make a character appear behind an object in the background texture

TheGrudgeTheGrudge Posts: 3Member
in 2D

Hi, I hope this question isn't stupid, I searched in Google for a while now but didn't came up with anything, maybe I'm using the wrong keywords?

I want to create a classic Point and Click Adventure like Monkey Island or Deponia. Currently I'm trying to make the character walk behind an object. The problem is: The whole scene is a painted background texture and the character can move inside of it. Now let's assume there is a trashcan in the background image, but I want the character to move behind it instead of walking in front of it.

Do I have to split my image up into several layers in Photoshop or some similar software, so that I have multiple layers that compose the background image in Godot?

As you can see in this screenshot, the player character is behind that machine, but the image looks like it is just one big texture rect.

I thought maybe there is something like a masking technique so if the player sprite enters an Area2D or something similar, the part that is occupied by the collision body will mask out the sprite so it looks like the character is actually moving behind the object.

What will be the best way to achieve something like in the screenshot? Right now I guess I need to use multiple Textures as layers and move between them?

Comments

  • TwistedTwiglegTwistedTwigleg Posts: 2,655Admin

    Welcome to the forums @TheGrudge!

    While I have not made such a game myself, I believe the most common way to achieve the effect is to split the image into multiple parts or layers, with each layer having a different z-index corresponding to its order. Then you can change the z-index of the entities to have them appear to move through the scene in such a way that suggests depth. At least, that is how I believe it is done, I mostly do 3D game development :sweat_smile:

  • cyberealitycybereality Posts: 927Moderator

    Well, Deponia on PS4 was actually made with a version of Godot, so it has to be possible.

    I think for really complex 3D modeled levels, you can render a depth map from Blender and then use this as the base depth texture (well you can do this like in lower level APIs, not sure if Godot exposes this for you). That would be useful for a Resident Evil 1 type of game.

    For a 2D point-and-click, that may be overkill (though I guess possible if you want to paint a depth map by hand). Another, and probably the most logical option, would be to save out individual object images with an alpha map and assign a z value to them. You could write code that would change the players z value as they moved through the world, and then swap the layer they are on to make them go behind a pole or a garbage can or whatever.

    You can use the property z_index to adjust the drawing order.
    https://docs.godotengine.org/en/stable/classes/class_node2d.html#class-node2d-property-z-index

    You can give the static objects a fixed z_index, and then you just need to code the part that adjusts the player z based on where they are standing. How to do that will depend on how the camera angle are set up. One simple way is to map lower positions on the screen with a higher z index, and then ramp down to the top of the screen. You'll have to get a good range of values though, and I'm not sure this would work with lots of objects or complex camera angles.

    You could also place a plane floor model (behind the real background) and do a raycast from the mouse to get the z value and use this for the z index. You'll need to match the floor to each background image, but this would give you a lot of control and you could match it up better. However, if you only have a few foreground objects, maybe this is a lot of work.

  • TheGrudgeTheGrudge Posts: 3Member

    Thanks for all your suggestions. I will try to "split" my background image into several layers and put them together in Godot.

    I'm new to Godot and I must say I really like it. I took a look at Unity before but I think Godot is suited better for 2D games and I like working with GDScript (as a longtime Python user it feels very similar :smile: )

  • cyberealitycybereality Posts: 927Moderator

    Another option is to use YSort. This will auto adjust the layer an object is on based on the y position.
    https://docs.godotengine.org/en/stable/classes/class_ysort.html

    This will give you less control, but would work automatically without any additional scripts. If you make the player and all objects have their origin at the bottom (for example at the player's feet or at the base of a trash can) then it should work I think.

  • TheGrudgeTheGrudge Posts: 3Member

    Thanks I will give it a try...

    For now I split my background image in Affinity Photo and put every foreground element on its own layer (a copy of the background image with an alpha mask).

    I imported these layers as sprites to have the z-index available and set the background to -999, the player to 3 and the foreground element to 200...

    Seems to work fine.

    I used a background node before, but these nodes don't have a z-index property... I can change the z-index via script if I need to (character coming from the left: z-index 0, coming from the right, z-index 400 or something like that). This way I could create a more "dynamic movement".

  • cyberealitycybereality Posts: 927Moderator

    Okay, whatever works for you.

Leave a Comment

BoldItalicStrikethroughOrdered listUnordered list
Emoji
Image
Align leftAlign centerAlign rightToggle HTML viewToggle full pageToggle lights
Drop image/file