Search code examples
c#unity-game-enginereplay

Replay level in the same scene who has many levels - Unity C#


By using Unity C# for game i try to create a replay level button in a scene who has many levels, already the levels manager is done, The point is when the game player loss in a level x111 and the panel game over show up, i wanna create a replay button level who can allow him to replay the same last level again who is the scene with the score also which had been available before.

I need help for it ?

Here's the script that i got to do until now

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

public class Balloon : MonoBehaviour {

    private Text ScoreText;
    public GameObject GameOverPanel;
    //private GameObject Restartbtn;

    private void Start () {
        ScoreText = GameManager.gm.GameplayUI.Find ("ScorePlaceholder").Find ("Score").GetComponent<Text> ();
    }

    private void Update () {
        ScoreText.text = Mathf.Max (0, Mathf.FloorToInt (transform.position.y)).ToString ();
    }

    private void OnTriggerEnter2D (Collider2D other) {
        if (other.tag == "Obstacle") {
            //print ("GAME OVER!");
            //SceneManager.LoadScene ("Gameplay");
            GameOverPanel.SetActive(true);
            Time.timeScale = 0f;
            }       
        else if (other.tag == "LevelEnd") {
            other.tag = "Untagged"; //Can trigger only once (needs, bcz balloon has 2 colliders)
            GameManager.gm.lm.SpawnLevel ();    
        }

    }

    public void Restartbtn() {

        //SceneManager.LoadScene("Gameplay");
        GameOverPanel.SetActive(false);
        //SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);
        //SpawnLevel method is from levelsmanger script, he just swap unto the next level like if the last level is already success   
        GameManager.gm.lm.SpawnLevel();
        //Application.LoadLevel("CurrentLevel");
        Time.timeScale = 1f;

    }

}

Here's the script of levels manager

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

public class LevelsManager : MonoBehaviour {

    public int currentLevel;
    public float levelSizeY;
    private Vector2 nextLevelPos;
    private Text LevelText;

    public GameObject [] levelPrefabs;
    private GameObject newLevel;
    private GameObject curLevel;
    private GameObject oldLevel;

    private void Start () {
        LevelText = GameManager.gm.GameplayUI.Find ("LevelPlaceholder").Find ("Level").GetComponent<Text> ();
        nextLevelPos = new Vector2 (nextLevelPos.x, nextLevelPos.y + levelSizeY);
        SpawnLevel ();
    }

    public void SpawnLevel () {
        LevelText.text = currentLevel.ToString () + "/69";
        currentLevel++;

        Destroy (oldLevel); //Removes old lvl
        if (currentLevel == 2) { oldLevel = GameObject.Find ("Level_Start"); }
        else { oldLevel = curLevel; } //Moves cur lvl to old lvl
        SetOrderLayer (oldLevel, "OldLevel");

        curLevel = newLevel; //Moves new lvl to cur lvl
        SetOrderLayer (newLevel, "CurrentLevel");

        int randomLvl = Random.Range (0, levelPrefabs.Length);
        newLevel = Instantiate (levelPrefabs [randomLvl], nextLevelPos, Quaternion.identity); //Makes new lvl
        newLevel.transform.Find ("LevelUI").Find ("LevelNr").GetComponent<Text> ().text = currentLevel.ToString ();
        SetOrderLayer (newLevel, "NewLevel");

        nextLevelPos = new Vector2 (nextLevelPos.x, nextLevelPos.y + levelSizeY);
    }

    private void SetOrderLayer (GameObject parentObject, string sortingLayerName) {
        if (parentObject) {
            for (int child = 0; child < parentObject.transform.childCount; child++) {
                if (parentObject.transform.GetChild (child).GetComponent<SpriteRenderer> ()) {
                    parentObject.transform.GetChild (child).GetComponent<SpriteRenderer> ().sortingLayerName = sortingLayerName;
                }

                for (int subChild = 0; subChild < parentObject.transform.GetChild (child).childCount; subChild++) {
                    if (parentObject.transform.GetChild (child).GetChild(subChild).GetComponent<SpriteRenderer> ()) {
                        parentObject.transform.GetChild (child).GetChild (subChild).GetComponent<SpriteRenderer> ().sortingLayerName = sortingLayerName;
                    }

                    for (int subSubChild = 0; subSubChild < parentObject.transform.GetChild (child).GetChild (subChild).childCount; subSubChild++) {
                        if (parentObject.transform.GetChild (child).GetChild (subChild).GetChild (subSubChild).GetComponent<SpriteRenderer> ()) {
                            parentObject.transform.GetChild (child).GetChild (subChild).GetChild (subSubChild).GetComponent<SpriteRenderer> ().sortingLayerName = sortingLayerName;
                        }
                    }
                }
            }
        } 
    }

}

Solution

  • If each scene represents a level in your project, you can create a button and add to your button this method when it's pressed:

    using UnityEngine.SceneManagement;
    
    public void RestartScene(){      
            Scene scene = SceneManager.GetActiveScene(); 
            SceneManager.LoadScene(scene.name);
    
        }//RestartScene
    

    For your current score, i think that you should store it in a script that doesn't get deleted when loading a scene by including this

    DontDestroyOnLoad(this.gameObject);
    

    I hope this is what you needed.