Search code examples
3dgodot

How to use Doors to load levels in godot 3d


just started playing around with Godot and I'm trying to figure out the best way to handle level switching in my game.

The game world is split into 3 distinct levels:

  1. Outside
  2. Inside Level 1
  3. Inside Level 2

Outside and Inside Level 1 are connected, and Inside Level 1 and Level 2 are connected

I need a way to make it so that when a player interacts with a door object the game loads the level necessary AND spawns the player at the correct spawn point. So when the player goes from Inside Level 1 to Outside, they need to spawn right infront of the door object in the Outside Level instead of Outside's default spawn location. The same is true of when the Player goes from Inside Level 2 back to Inside Level 1.

I just learned about singletons/autoload so I figure I need to set up some kind of level manager but Im not exactly sure how. I also don't know how to set the player's transform to be the same as the spawn point.


Solution

  • Yes, use an autoload.

    We can really over-engineer this. There are many variations, as you will see below. But there are a set of steps you are going to follow. In the interest of not bloating this answer, I'll cover them in broad terms.

    This is what you are going to do:

    • In the scenes add a Position3D for each door. This Position3D will be where you will place the player character when it enters from the corresponding door. And give the Position3D a name that you can figure out form the name of the door.
    • Store in a variable in the autoload which door the player interacted with. This is what we are going to use to find the Position3D on the new scene. The code in the door will either call a method on the autoload, or set the variable directly.
    • Change scenes, by whatever means you prefer (it can be from the code in the door, or a method in the autoload - it can be with the scene tree methods or manually - you can load, preload or load interactively the new scene). Interactive load avoid freezing the game during the load. Which allows you have an animation to hide the load time.
    • After the new scene is loaded, instantiated and in the scene tree… Get the corresponding Position3D with the value stored in the autoload (if there is any).
    • Now you are going to place the player character at the Position3D you found. This might mean to move it, if you have the player character as part of the scene. Or a method in the autoload spawns the character in the correct position. Or you might even remove the player character from the old scene, store it in the autoload, and after the new scene is ready, add it to it. In fact, it is possible to make the player character itself an autoload. Regardless of how you get the reference to the character player, you are going to make sure its global_transform is set to the global_transform of the Position3D you found (if there was any). If there wasn't, then put (or let) the player character at a default position.

    Addendum: If you only want the position instead of the transform, you can use global_transform.origin. There isn't a global_position in 3D in Godot 3, however it was added in Godot 4.