Level 3 has coins and enemies from Level 1

Hi there,

Something is bugged in my code.

When transitioning from Level 2 to Level 3 all Enemy and Coin Placements in Level 3 are the ones of Level 1. When I start level 3 directly the placements are correct. How come the game loads the ScenePersist Object from lvl 1 in lvl 3 when transitioning from lvl 2 to lvl 3?

ScenePersist.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ScenePersist : MonoBehaviour
{
    void Awake()
    {
        int numScenePersists = FindObjectsOfType<ScenePersist>().Length;
        if (numScenePersists > 1)
        {
            Destroy(gameObject);
        }
        else
        {
            DontDestroyOnLoad(gameObject);
        }
    }
    public void ResetScenePersist()
    {
        Destroy(gameObject);
    }
}

GameSession.cs

using System;
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.SceneManagement;

public class GameSession : MonoBehaviour
{
    [SerializeField] int playerLives = 3;
    [SerializeField] TextMeshProUGUI livesText;
    [SerializeField] TextMeshProUGUI scoreText;
    [SerializeField] int playerScore = 0;

    void Awake()
    {
        int numGameSessions = FindObjectsOfType<GameSession>().Length;
        if (numGameSessions > 1 )
        {
            Destroy(gameObject);
        }
        else
        {
            DontDestroyOnLoad(gameObject);
        }
    }

    void Start()
    {
        livesText.text = playerLives.ToString();
        scoreText.text = playerScore.ToString();
    }

    public void ProcessPlayerDeath()
    {
        if (playerLives > 1)
        {
            TakeLife();
        }
        else
        {
            ResetGameSession();
        }
    }

    public void AddToScore(int pointsToAdd)
    { 
        playerScore += pointsToAdd;
        scoreText.text = playerScore.ToString();
    }

    void TakeLife()
    {
        playerLives--;
        int currentSceneIndex = SceneManager.GetActiveScene().buildIndex;
        SceneManager.LoadScene(currentSceneIndex);
        livesText.text = playerLives.ToString();
    }

    void ResetGameSession()
    {
        FindObjectOfType<ScenePersist>().ResetScenePersist();
        SceneManager.LoadScene(0);
        Destroy(gameObject);
    }
}

LevelExit.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;

public class LevelExit : MonoBehaviour
{
    [SerializeField] float levelLoadDelay = 1f;
    private void OnTriggerEnter2D(Collider2D other)
    {
        if (other.tag == "Player")
        {
            StartCoroutine(LoadNextLevel());
        }
        
    }

    IEnumerator LoadNextLevel()
    {
        yield return new WaitForSecondsRealtime(levelLoadDelay);
        int currentSceneIndex = SceneManager.GetActiveScene().buildIndex;
        int nextSceneIndex = currentSceneIndex + 1;

        if(nextSceneIndex > SceneManager.sceneCount)
        {
            nextSceneIndex = 0;
        }

        FindObjectOfType<ScenePersist>().ResetScenePersist();
        SceneManager.LoadScene(nextSceneIndex);
    }

}

When transitioning from lvl2 to lvl3

When starting lvl3 directly

ScenePersist of lvl1
scenepersist3

Game objects are only really destroyed at the end of the frame. I suspect this may be the problem here because the scene is loaded before the end of the frame and the destroy is ‘cancelled’ (I feel I’m wrong, though). Put a yield return null; between these two lines and see if it makes a difference.

1 Like

Thank you for your reply. I will try it later on today and give you feedback.

now it jumps from level 2 to level 1

Check your scenes in File > Build Settings. Scene 1 should be above scene 2.

Check that all the scenes are in the build settings. Go to File -> Build Settings... and check that it is in the ‘Scenes In Build’ list.


Edit
Oh, Nina got you

They are all in there and in the right order.

How is it possible then that level 1 gets loaded after level 2? Don’t you load the “next” scene from the build settings? See LoadNextLevel() in LevelExit.

Have you already tried to add Debug.Logs to your code to see what is going on during runtime?

1 Like

OK first, this is going to overshoot. If you have 3 levels, you only want to count to 2 (we start counting at 0) but this will count to 3. Just change > to >=

Then, I’m wondering if you don’t have the coroutine executing multiple times. You only want this executing once. StartCoroutine returns a Coroutine object. You can store that and if it already exists, don’t start the coroutine again

public class LevelExit : MonoBehaviour
{
    private Coroutine nextLevelRoutine;

    private void OnTriggerEnter2D(Collider2D other)
    {
        if (other.CompareTag("Player") && nextLevelRoutine == null)
        {
            nextLevelRoutine = StartCoroutine(LoadNextLevel());
        }
    }

    // etc.

}
1 Like

It’s all working now, the correct code was:

if (nextSceneIndex == SceneManager.sceneCountInBuildSettings)
        {
            nextSceneIndex = 0;
        }

Whilst I had:

if(nextSceneIndex > SceneManager.sceneCount)
        {
            nextSceneIndex = 0;
        }

Not sure if this was updated somewhere in a lesson and I missed it. But ti"s solved now.

Thank you for pointing out that line of code to me!!!

Good job on solving the problem! :slight_smile:

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.

Privacy & Terms