Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

LoadScene not loading the correct scene

Discussion in 'Scripting' started by devinmcphee, Jun 25, 2022.

  1. devinmcphee

    devinmcphee

    Joined:
    Oct 22, 2015
    Posts:
    4
    I'm pretty new to Unity, and I'm working on a prototype that involves switching back and forth between different scenes. I'd like to be able to jump from Scene A, to Scene B, to Scene C, back to Scene B, back to Scene A, etc.

    I've got a trigger prefab with a scene switch script, using SceneManagement. It has a public field (I've tried both int and string) with the target scene.

    If I step on the trigger, I get an 'E' prompt, and when I press E, I jump to the target scene. However, if I have two instances of the same prefab, even with different targets in each public field, both triggers lead to the same scene.

    So say I'm in "Scene B", and I put two instances of the prefab. One has the target "Scene A" and one has the target "Scene C". But both trigger boxes lead to "Scene A"

    For what it's worth, I've got a Debug.Log("Player on Switch to " + sceneName); and it displays the correct scene name. But when I hit E, it sends me to the wrong scene.
    I'm not getting any errors, and I've checked Unity's SceneManagement documentation, but honestly I'm still too new to Unity/C# to really grasp where I'm going wrong. I've watched a pile of Youtubes and Googled for hours. I'm sure it's simple as heck, and I'm just missing something basic.

    Here's what my prefab script looks like:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.SceneManagement;
    5. using UnityEngine.UI;
    6.  
    7. public class LayerSwitch2 : MonoBehaviour
    8. {
    9.  
    10.     public Canvas EPromptCanvas;
    11.     public string sceneName;
    12.  
    13.     void OnTriggerEnter(Collider other)
    14.     {
    15.         if (other.tag == "Player")
    16.         {
    17.             Debug.Log("Player on Switch to " + sceneName);
    18.             //show prompt
    19.             EPromptCanvas.enabled = true;
    20.         }
    21.     }
    22.  
    23.     private void OnTriggerExit(Collider other)
    24.     {
    25.         if (other.tag == "Player")
    26.         {
    27.             Debug.Log("Player leaves Switch");
    28.             //disable prompt
    29.             EPromptCanvas.enabled = false;
    30.         }
    31.     }
    32.  
    33.     private void Update()
    34.     {
    35.         if(EPromptCanvas.enabled == true && (Input.GetKey(KeyCode.E)))
    36.         {
    37.             loadLevel();
    38.         }
    39.     }
    40.  
    41.     public void loadLevel()
    42.     {
    43.         SceneManager.LoadScene(sceneName);
    44.     }
    45. }
    46.  
    Any idea what I'm doing wrong?

    (PS: For clarity -- and feel free to ignore this, but just in case I might be going about this whole thing the wrong way entirely, and someone has suggestions to gently nudge me in the right direction -- each scene has a different character, with different controls, camera, etc. So when the character in Scene A interacts with the scene switch trigger, it activates a character in Scene B. The Scene B character might, for example, need to hit a switch in Scene B in order to unlock a door for the character in Scene A. Y'know what I'm saying? Anyway.)

    Thanks!
     
    Last edited: Jun 25, 2022
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,797
    Nope, but through the magic of debugging, here's how you can find out!

    What is often happening in these cases is one of the following:

    - the code you think is executing is not actually executing at all
    - the code is executing far EARLIER or LATER than you think
    - the code is executing far LESS OFTEN than you think
    - the code is executing far MORE OFTEN than you think
    - the code is executing on another GameObject than you think it is
    - you're getting an error or warning and you haven't noticed it in the console window

    To help gain more insight into your problem, I recommend liberally sprinkling Debug.Log() statements through your code to display information in realtime.

    Doing this should help you answer these types of questions:

    - is this code even running? which parts are running? how often does it run? what order does it run in?
    - what are the values of the variables involved? Are they initialized? Are the values reasonable?
    - are you meeting ALL the requirements to receive callbacks such as triggers / colliders (review the documentation)

    Knowing this information will help you reason about the behavior you are seeing.

    If your problem would benefit from in-scene or in-game visualization, Debug.DrawRay() or Debug.DrawLine() can help you visualize things like rays (used in raycasting) or distances.

    You can also call Debug.Break() to pause the Editor when certain interesting pieces of code run, and then study the scene manually, looking for all the parts, where they are, what scripts are on them, etc.

    You can also call GameObject.CreatePrimitive() to emplace debug-marker-ish objects in the scene at runtime.

    You could also just display various important quantities in UI Text elements to watch them change as you play the game.

    If you are running a mobile device you can also view the console output. Google for how on your particular mobile target, such as this answer or iOS: https://forum.unity.com/threads/how-to-capturing-device-logs-on-ios.529920/ or this answer for Android: https://forum.unity.com/threads/how-to-capturing-device-logs-on-android.528680/

    Another useful approach is to temporarily strip out everything besides what is necessary to prove your issue. This can simplify and isolate compounding effects of other items in your scene or prefab.

    Here's an example of putting in a laser-focused Debug.Log() and how that can save you a TON of time wallowing around speculating what might be going wrong:

    https://forum.unity.com/threads/coroutine-missing-hint-and-error.1103197/#post-7100494

    You must find a way to get the information you need in order to reason about what the problem is.
     
  3. lordconstant

    lordconstant

    Joined:
    Jul 4, 2013
    Posts:
    389
    Its more than likely not recognising the name and loading the first scene it knows every time. Have you added all the scenes you want to load between to the build settings? If not got to "File" in the top left go down to "Build Settings" and in the windows that pops up you can add the current open scene.
     
  4. bplc

    bplc

    Joined:
    Mar 10, 2022
    Posts:
    104
    Hello,
    personally I don't see any error, your script says that if your character enters your trigger, you activate EPromptCanvas and if you click on E you go to your sceneName.

    Do you have several LayerSwitch2 script in the same scene, with a different "sceneName" ?
    (example on several characters)

    It might be good if this is the case to activate or deactivate the script or character, when they are not used.
     
  5. devinmcphee

    devinmcphee

    Joined:
    Oct 22, 2015
    Posts:
    4
    Thanks for the replies

    Yeah I've got the scenes listed in build settings, and I've tried both the scene number integers and the string names.

    Thanks, I'll try to give it a shot, and I'll let you know if it fixes the problem.

    After staring at a wall for a while and having a think, I thiiiink I know what's going on. But it's just a matter of figuring out how to solve it aha. I think that since I have the level switching on the E prompt, and don't have any tags differentiating the two prefabs, it's firing the first instantiation every time.

    Like, the player is on a trigger, and E is pressed, therefore the first instantiated level is loaded.
    So maybe I'd need some kind of tag differentiating which prefab is which, and only fire if both the prefab tag and player trigger collision tags are true. Maybe..
     
  6. bplc

    bplc

    Joined:
    Mar 10, 2022
    Posts:
    104
    Yes, deactivate or add a condition ^^ I hope you will manage to solve your problem ^^
     
  7. devinmcphee

    devinmcphee

    Joined:
    Oct 22, 2015
    Posts:
    4
    Here's my temporary fix. It isn't 100% what I'm looking for, but it's good enough for now at this stage of the prototype.

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.SceneManagement;
    5. using UnityEngine.UI;
    6.  
    7. public class LayerSwitch2 : MonoBehaviour
    8. {
    9.  
    10.     public Canvas EPromptCanvas;
    11.     private string sceneIndex;
    12.     public bool forwardSwitch;
    13.  
    14.     public GameObject otherSwitch;
    15.     private int nextScene;
    16.     private int prevScene;
    17.  
    18.  
    19.     private void Start()
    20.     {
    21.         nextScene = SceneManager.GetActiveScene().buildIndex + 1;
    22.         prevScene = SceneManager.GetActiveScene().buildIndex - 1;
    23.     }
    24.  
    25.     void OnTriggerEnter(Collider other)
    26.     {
    27.         if (other.tag == "Player")
    28.         {
    29.             //show button prompt
    30.             EPromptCanvas.enabled = true;
    31.             //disable the other switch
    32.             otherSwitch.SetActive(false);
    33.         }
    34.     }
    35.  
    36.     private void OnTriggerExit(Collider other)
    37.     {
    38.         if (other.tag == "Player")
    39.         {
    40.             Debug.Log("Player leaves Switch");
    41.             //disable button prompt
    42.             EPromptCanvas.enabled = false;
    43.             //enable the other switch
    44.             otherSwitch.SetActive(true);
    45.         }
    46.     }
    47.  
    48.     private void Update()
    49.     {
    50.         if(EPromptCanvas.enabled == true && (Input.GetKey(KeyCode.E)) && forwardSwitch == true)
    51.         {
    52.             jumpToNextLevel();
    53.         }
    54.         if (EPromptCanvas.enabled == true && (Input.GetKey(KeyCode.E)) && forwardSwitch == false)
    55.         {
    56.             jumpToPrevLevel();
    57.         }
    58.  
    59.     }
    60.  
    61.     public void jumpToNextLevel()
    62.     {
    63.         SceneManager.LoadScene(nextScene);
    64.     }
    65.  
    66.     public void jumpToPrevLevel()
    67.     {
    68.         SceneManager.LoadScene(prevScene);
    69.     }
    70. }
    71.  
     
    bplc likes this.
  8. bplc

    bplc

    Joined:
    Mar 10, 2022
    Posts:
    104
    Good ^^