How can I get my player to spawn at player start when a new level is loaded?

Hello,

I am trying to get my player to start at the player start when a level is loaded. I save my players location throughout each level. When I load into a new level, oftentimes the location is still set to the location the player was last at in the other level. To combat this I got the coords of each player start and set the players location to those coords.

This actually works in the editor when I run standalone or new editor window. However, when I package the game and run the packaged game it will not work and everything is black on the screen.

How can I fix this or do it better?

By default, the GameMode is responsible for placing the player Characters at player start locations.
Where are you saving the player locations? In your screenshot I see you’re setting the location to some saved parameter. What is this value?

You should wait for the level to load. When it does, you can trigger the event in the game mode (which handles the restart player functions) to restart player at transform.

If you use player starts, you can get actor of class as playerstart, and if there are multiple starts, then get all actors of class and put them in an array. Then you can restart player at a player start or just restart player and it should pick a random player start that isn’t occupied.

My player location gets saved at certain checkpoints. When the player reaches the level end I change this saved location value to the location of player start in the new world that is loading. This value is saved in the first person player bp.

How do I wait for the level to fully load? I have actually also had issues where in the packaged game the levels materials arent fully loaded in and they are very blurry.

I tried this but the player ends up in a black screen area where none of the games keybinds work anymore.

I tried this is my gamemode class but it doesnt work either. The player died one works but the level load does not.

This also does not work. It spawns me in a different area of the map.

Use a get all actors of class with tag. You can place as many player starts as you want and just set up some tags for each one: Tag:Checkpoint1, while another player start in the same map can have tag Checkpoint2.
Make sure you’re having the tag variable saved on pre-map change, and loaded back in from a save file on load, assuming its not somehow already doing it (im use to doing multiplayer stuff, not singleplayer).

edit: Also im not entirely sure (again i do multiplayer stuff) but its possible the moment it opens a level, it ends the logic. For me in multiplayer i have each map as a seperate server so i have to save anything critical to the database and load it back up upon enter of the new map. For singleplayer where its just an open level node, it may work just fine, i cant say for certain haha. easy way to tell is to add a delay for 10 seconds after it opens the level and does a print string saying ‘LOGIC CONTINUED’, then atleast you’ll know its definitely continuing logic after level load.

Do keep in mind that upon start, its going to place your character at a random player start. This is just basic UE code. Once your character loads in, it’ll be a random location on any one of the player starts then your code will kick in where as long as you have a location tag variable set and it runs that code from up above then it’ll move you to that location.

Unless this new level is being loaded as a level instance, or you’re marking the player character as persistent through seamless travel (and using seamless travel when loading the new level), the character in the new level should be completely new, and spawned + placed at a player start by the default game mode. You shouldn’t need to set the position manually at all.
Unless you’re wanting to spawn the player at a specific player start based on some trigger that cause the level load? In that case, you’d likely work with player start Tags, and set the tag on an object that persists between level loads (such as the GameInstance) before loading the level. Then in the game mode, look through the overridable functions (I work with C++ usually, so I’m not sure what is blueprint accessible). If there is something like “choose player start” or “Restart player” or something similar, try overriding it and choosing a player start by tag. I believe one of the previous commenters discussed this.

My player right now is only created one time. I end up loading the new level and moving its position to the start location of the new level once it gets loaded behind a loading screen.

Im at a point in development where doing what you suggested will take too much time and simply wont work. Id have to redo almost all of my player code. One of my biggest mistakes I think, is that my main game functionality is all inside my player class. So the player contains the code to do almost everything in my game.

EDIT: Another issue that I am having is when the player loads into a new level, then they return to the main menu, when they re-enter the game the level does not load because the game doesnt know which level to load.

Characters are created by the GameMode, and are cleaned up when a world is destroyed (say, when loading a new level, the old level’s world is destroyed once the new one is ready). This means that unless you’re doing something strange, your character will be reinstantiated in the new world. It may look the same, and be the same class, but it should be a new instance.
You could easily test this by adding a PrintString in the Player’s construction script. If this prints each time a level change happens, you are creating a new character.
Now, if you confirm this, try to find all the places where you are setting the position of the player. Let me know what you find.

Oh, and even if you’re using seamless travel (which keeps some actors around between level transitions) technically it creates a new actor in the new world and copies data from the old world’s actor into the new one. So even then it is creating a new actor.

1 Like

You are correct. It seems that even when I load into a new world the construction script prints hello.

So there is server travel. This means that while the level is loading, you have a little level which is like a loading screen. It loads the new level in the background before it switches you to the new level.

The player controller is persistent and stays loaded and doesn’t restart when the next level pops up, so you need to get all your stuff set up for the new level after the new level loads. You can have a “Recast” event on your controller which will reset any variables to start position. The game usually creates a new pawn so you will probably need to reset those variables too and get the new reference.

Some other things aren’t persistent either. I don’t have a persistent GameState for example but my GameMode is persistent. I don’t have a persistent Hud either. Point being, anything that persists will have the references and stuff from the old level.

If you have the level wait like 0.1 seconds for any spawners to spawn objects into the level, and then have it get player 0 controller and then have it call the function “Recast” then it will get the actor of class from the new level and the location etc.

The best way is to do the restart player in the game mode like you have but the thing is, you need the playerstart to be there before it can restart the player. Also you should have the new level get the GameMode, cast to the GameMode and then trigger LoadLevel, it will then do the restart and the character position will be restarted.

With the games, the controller is like the foreman telling all the workers what to do, and communicating with the boss of the factory. The character is like a worker, handling it’s own stuff based on what it’s told to do by the foreman. The boss of the factory is like the GameMode. It doesn’t really talk to the workers but it can hard ball move workers in and instant. It handles where everyone starts and where they start their work. The Game State is like a secretary that has all the information about the state of the factory. It’s a great place to handle all the scores and multicasts from the GameMode. Like the GameMode tells the GameState to tell everyone that something has happened. PlayerState is like a performance evaluator for the worker, just keeping and eye on all the information about the player. So you can store stuff there like What clothes the player is wearing etc. And if something needs to know about the player, it can access the Player State.

Point being, You’re a controller, telling a character what to do in the factory level. The boss GameMode can talk to the controller but usually the GameMode boss gets the GameState to handle the operations of the factory. GameMode mainly handles the positioning of characters and overall running of the core of the game. Win Conditions, level transitions etc, based on what the GameState information.

I also have a HUD actor too which handles all my widget stuff. Controller just asks the Hud to create or destroy stuff and the Hud does all the work

So try to have each section do it’s own job. When you have 1 thing doing everything, it gets messy and you can’t really debug well. If it’s a widget creation error, then where in the haystack of code would it be? With the HUD handling creation, you know exactly who to go to to deal with the problem.

Imagine a factory where everyone does every job for themselves. So they pay themselves and order their own gear and fix their own machines and other peoples machines. When something goes wrong, who do you talk to? Where do you go looking for the problem?

So if you can look at setting all that up in a similar way you will find the process gets much easier. And if you ever go to multiplayer, you’ll be thankful you did.