How to create different height levels in a top-down 2D game?

Godot Version



When I say top-down, I don’t mean directly 90° top-down like the older GTA games. I mean like 45° top-down like the older Pokémon games. I want to make a catwalk, which is a walkway that is elevated above the ground. The floor of the elevated part of the catwalk should be above the player when the player is on the ground level and below the player when the player is on the catwalk.

So to do this, I created two separate collision layers for the stairs and ground floor, and 4 separate TileMap layers for the stairs and ground floor. When the player enters the stairs trigger, then the player will switch collision layers and the TileMap will change the ordering of its layers.

The problem is, now I want the player to move up automatically when moving up the stairs and move down when moving down the stairs. Before, the stairs trigger was covered by a collision shape so that the player could only enter it one way, but if I want the player to walk down the stairs automatically, then the trigger must cover the entire stairs and go past the collision shape. So I did that, but now I need to know how to tell if the player is entering the stairs trigger from on the catwalk (so I will adjust their vertical velocity) or is entering the stairs from the ground level in the right direction (so I will adjust their vertical velocity) or is entering the stairs from the ground level in the wrong direction (so I will do nothing).

So I wrote a bunch of if statements to do it, but it really seems like this is getting more and more hacked together as it goes on. What if I want to put in more than one level of the catwalk? I will need to create at least 3 more layers (1 physics, 2 TileMap) for each level and even more if I want to add stuff like enemies and pushable objects and light on the TileMap.

Is there a better way of doing this, or should I just make the player unable to walk underneath the catwalk?


I will soon face this problem in my project so I would be interested in a solution too.

I did not implement anything by now so I am not sure of the feasibility of this, but here’s an idea for a solution that comes to mind :

  • Use one tilemap for all the floors, and spread the floors on the entire tilemap
  • Use some nodes that makes the connections between the different floors. For example a staircase on the first floor that connects to a staircase on the second floor. Depending on your needs, these nodes should manage more or less things (teleport things from a node to the other, handle navigation region connections, etc.)
  • If you want to see floor 1 from floor 2, add a camera that will capture floor 1 and a viewport texture beside floor 2 that will render this camera

With this solution :

  • All physic and rendering layers should be the same since the floors do not overlap.
  • The interactions between floors are handled by your connection nodes so you can make it simple in the first place and make it more complex in the future. For example : first you could only handle player teleportation between floors, then you could handle npc navigation between floors, then objects that could fall from a floor to the floor beside, etc.

Thanks for the suggestions! I will see if they work for my game.