I have a level menu and I tried to make it so when you complete the next level it is unlocked in the menu. I dont know why it isnt unlocking the level after I beat it but maybe someone can help. Here is the code for the end object and the level selector stuff
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class MoveToNextLevel : MonoBehaviour
{
public int nextSceneLoad;
// Start is called before the first frame update
void Start()
{
nextSceneLoad = SceneManager.GetActiveScene().buildIndex + 1;
}
public void OnTriggerEnter(Collider other)
{
if (other.gameObject.tag == "Player")
{
SceneManager.LoadScene(nextSceneLoad);
if(nextSceneLoad > PlayerPrefs.GetInt("levelAt"))
{
PlayerPrefs.SetInt("levelAt", nextSceneLoad);
}
}
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class LevelSelection : MonoBehaviour
{
public Button[] lvlButtons;
// Start is called before the first frame update
void Start()
{
int levelAt = PlayerPrefs.GetInt("LevelAt", 2);
for (int i = 0; i < lvlButtons.Length; i++)
{
if (i + 2 > levelAt)
lvlButtons[i].interactable = false;
}
}
}
My guess is because you’re loading the next scene before setting the “levelAt” value.
The MoveToNextLevel script gets destroyed as the next scene loads before it can continue past SceneManager.LoadScene(nextSceneLoad);.
Try simply moving this line after the if-statement:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class MoveToNextLevel : MonoBehaviour
{
public int nextSceneLoad;
// Start is called before the first frame update
void Start()
{
nextSceneLoad = SceneManager.GetActiveScene().buildIndex + 1;
}
public void OnTriggerEnter(Collider other)
{
if (other.gameObject.tag == "Player")
{
if (nextSceneLoad > PlayerPrefs.GetInt("levelAt"))
{
PlayerPrefs.SetInt("levelAt", nextSceneLoad);
}
SceneManager.LoadScene(nextSceneLoad);
}
}
}
Try putting some Debug.Log statements wherever you call PlayerPrefs.GetInt("levelAt"); to check what the value of it is and see if it’s being updated.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class MoveToNextLevel : MonoBehaviour
{
public int nextSceneLoad;
// Start is called before the first frame update
void Start()
{
nextSceneLoad = SceneManager.GetActiveScene().buildIndex + 1;
}
public void OnTriggerEnter(Collider other)
{
if (other.gameObject.tag == "Player")
{
if (nextSceneLoad > PlayerPrefs.GetInt("levelAt"))
Debug.Log("HELLO");
{
PlayerPrefs.SetInt("levelAt", nextSceneLoad);
}
SceneManager.LoadScene(nextSceneLoad);
}
}
}
So either your Player GameObject is missing the “Player” tag… if (other.gameObject.tag == "Player")
…Or the value of “nextSceneLoad” is not greater than the value of “levelAt” in your player prefs: if (nextSceneLoad > PlayerPrefs.GetInt("levelAt"))
Log both of these values to make sure they’re correct:
public void OnTriggerEnter(Collider other)
{
Debug.Log("Detected object tag: " + other.gameObject.tag);
if (other.gameObject.tag == "Player")
{
Debug.Log("Player was detected");
Debug.Log("nextSceneLoad = " + nextSceneLoad);
Debug.Log("levelAt = " + PlayerPrefs.GetInt("levelAt"));
if (nextSceneLoad > PlayerPrefs.GetInt("levelAt"))
{
PlayerPrefs.SetInt("levelAt", nextSceneLoad);
Debug.Log("levelAt after setting = " + PlayerPrefs.GetInt("levelAt"));
}
SceneManager.LoadScene(nextSceneLoad);
}
}
You need to put the debug log statement inside the curly brackets, otherwise PlayerPrefs.SetInt is always going to happen.
Other than that, follow Vryken’s advice and put debug log statements everywhere until you find where the flow of execution stops. If nothing is in the console, put more debug log statements in until something appears in the console.
This is my code now and HELLO appears in the console only when a knew scene starts not when a scene resets
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class MoveToNextLevel : MonoBehaviour
{
public int nextSceneLoad;
// Start is called before the first frame update
void Start()
{
nextSceneLoad = SceneManager.GetActiveScene().buildIndex + 1;
Debug.Log("HELLO");
}
public void OnTriggerEnter(Collider other)
{
if (other.gameObject.tag == "Player")
{
Debug.Log("HELLO");
if (nextSceneLoad > PlayerPrefs.GetInt("levelAt"))
{
PlayerPrefs.SetInt("levelAt", nextSceneLoad);
Debug.Log("HELLO");
}
SceneManager.LoadScene(nextSceneLoad);
Debug.Log("HELLO");
}
}
}
Please use the test code I added in my last post, because saying that “HELLO” only gets printed out once here doesn’t really help much when you have multiple places where “HELLO” can be printed out.
It’s probably the one in the Start method that’s getting printed and that’s it.
We still haven’t determined if your Player GameObject has the “Player” tag or if the value of “nextSceneLoad” is actually greater than the value of “levelAt”.
Run your scene using the test code from my previous post and move your Player GameObject inside this MoveToNextLevel script’s trigger Collider2D.
If this Debug statement doesn’t print… Debug.Log("Detected object tag: " + other.gameObject.tag);
…Then your Player GameObject is missing a trigger Collider2D component.
If this Debug statement doesn’t print… Debug.Log("Player was detected");
…Then your Player GameObject is missing a “Player” tag.
If this Debug statement doesn’t print… Debug.Log("levelAt after setting = " + PlayerPrefs.GetInt("levelAt"));
…Then the value of “nextSceneLoad” is not greater than the value of “levelAt”.