简体   繁体   中英

UnityException: GetActiveScene is not allowed to be called from a MonoBehaviour constructor

I'm trying to make a save level system and I keep on getting this error.

UnityException: GetActiveScene is not allowed to be called from a MonoBehaviour constructor

I've tried searching this up, but there were no results. Here is the code I used:

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

public class EndLevel : MonoBehaviour
{
    public PlayerMovement pm;

    public GameObject completeLevelUI;

    // Start is called before the first frame update
    void Start() { 
    }

    // Update is called once per frame
    void Update() {
    }

    void OnCollisionEnter (Collision collisionInfo) {
        if(collisionInfo.collider.tag == "Finish") {
            Debug.Log("You beat the level!");
            pm.enabled = false;
            completeLevelUI.SetActive(true);
            Level = Level + 1;
            PlayerPrefs.SetFloat("Level", Level);
            Debug.Log("Saved");
            Invoke("NextLevel", 3);
        }
    }

    public void NextLevel() {
        SceneManager.LoadScene (SceneManager
            .GetActiveScene().buildIndex + 1);
    }
}

Any Ideas about the error?

You have to get the current active Scene in the Start() or Awake() methods.

Example with Start() :

private int sceneNumber;

private void Start() {
    sceneNumber = SceneManager.GetActiveScene().buildIndex;
}

As an alternative solution you could also use a Lazzy Getter. Which means that the value won't get stale between when the scene loads and when you use it, which might matter with other pieces of data.

Example with Lazzy Getter:

private int sceneNumber { 
    get { 
        return SceneManager.GetActiveScene().buildIndex; 
    }
}

When you use either of those solutions, you can now simply call scenenumber + 1 in your SceneManager.Load() function call instead.

Additionally you need to ensure that you are calling an IEnumerator , instead of Invoking the Function call. If you want to delay the scene loading.

Function Call:

private void OnCollisionEnter (Collision collisionInfo) {
    ...
    StartCoroutine(NextLevel(3f));
    ...
}

private IEnumerator NextLevel(float seconds) {
    yield return new WaitForSeconds(seconds);
    SceneManager.LoadScene(sceneNumber + 1);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM