How do I spawn player in certain places between scenes?

Hi there,

I have a game where the player goes through various scenes as well as through an overworld. I have scripts in place that can transfer players from scene to scene, but they will always restart with the player where it was initially placed in my scene. It’s important that when a player goes from scene to scene they spawn in the corresponding area from where they were (Eg. If they exit one scene to overworld, they spawn in the overworld where they entered the previous scene). Unfortunately I don’t know how I might code that or how I might carry data between scene to scene since it seems to discard most previous data when transferring between scenes. I know this is possible, but I have no idea how I’d do it.

Is there a way to store data between scenes as well as spawn a player in certain places depending on where they are coming from?

Note: Please give me some code examples if possible. I am making this game by myself, but I’m mostly an artist, not a programmer. I do mostly understand and can read code, but I am very bad at thinking of how to program things by myself. I would really appreciate some code examples that I can try to adapt.

We’re doing this in our game with a simple SceneLoader script marked with DontDestroyOnLoad. This means that the script lives between scenes. The SceneLoader is a singleton, which is a pattern where you can access it from anywhere in code, and there’s only one of it that exists.

Whenever our player character enters an exit level trigger, that trigger notifies the SceneLoader about where in the scene the character was.

Then, when we load a scene, the SceneLoader uses OnLevelWasLoaded to spawn the player, and place it on the correct spot based on where it left the last scene.

This is significantly easier if you have scenes that match perfectly - ie. you could place them next to each other, and the entrances and exits would match. Then you can just flip the coordinates of the level exit to the the level entrance spot. If that’s not the case, you can give the triggers matching names that you send to the Scene Loader.

In that case, the level triggers would have something like:

public class ExitTrigger : MonoBehaviour {

    public string triggerName; //this should match on both ends
    public string levelToLoad; //what level this trigger leads to
    public Transform spawnPoint; //where the player should spawn. IMPORTANT: not inside this trigger

    void OnTriggerEnter(Collider c) {
        if(//check if c is the player) {
            SceneLoader.instance.OnEnteredExitTrigger(triggerName, levelToLoad);
        }
    }

public class SceneLoader : MonoBeaviour {

    //singleton stuff. This makes the SceneLoader be created the first time you need it
    private static SceneLoader _instance;
    public static SceneLoader instance {
        if(_instance == null) {
            GameObject loaderHolder = new GameObject("[Scene Loader]");
            _instance = loaderHolder.AddComponent<SceneLoader>();
        }
        return _instance;
    }

    private string lastTrigger;

    public void OnEnteredExitTrigger(string triggerName, string levelToLoad) {
        lastTrigger = triggerName;
        Application.LoadLevel(levelToLoad);
    }

    void OnLevelWasLoaded() {
        GameObject playerObject = //Spawn player here

        ExitTrigger[] allExits = FindObjectsOfType<ExitTrigger>();
        foreach(ExitTrigger exit in allExits ) {
            if(exit.triggerName == lastTrigger) {
                playerObject.transform.position = exit.spawnPoint.position;
                return;
            }
        }
        //handle there not being any sceneloaders here somehow.
    }
}

That’s a very simplified version, but it should get you started.