Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Question Trying to switch between scenes after my player character enters a collider and presses a key

Discussion in 'Scripting' started by Kerdar, Jul 25, 2021.

  1. Kerdar

    Kerdar

    Joined:
    Jan 11, 2021
    Posts:
    8
    so I am fairly new to unity and I am facing a problem with scene switching. I am prototyping a 2D dungeon crawler with doors that the player can interact with to load other scenes. My script is down below:

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.SceneManagement;
    public class OnTriggerLoadLevel : MonoBehaviour
    {
    public GameObject guiObject;
    void Start()
    {
    guiObject.SetActive(false); //setting the gui element to deactivated from the beginning
    }
    void OnTriggerEnter2D (Collider2D Player)
    {
    if (Player.gameObject.tag == "Player")
    {
    guiObject.SetActive(true); //when the collision happens, the gui element gets activated and shows "press [E] to enter" on the screen
    if (Input.GetButton("use")) //with the collision active, when 'E' is pressed scene with index 1 will load
    {
    SceneManager.LoadScene(1); //load scene with index 1 in the build settings
    }
    }
    }
    void OnTriggerExit2D() //when the collision stops, the gui element gets deactivated
    {
    guiObject.SetActive(false);
    }
    }

    the UI element gets activated and shown on the screen so that means the script is entering and starting to run the code in the trigger function.
    I thought the problem might be with loading the next scene and that the script is detecting the E keypress, so I did some debugging by writing a Debug.Log ("pressing E"); printed into the console when I press E inside the if statement in the trigger function and before the LoadScene(). Apparently, the code is not even entering the if statement as nothing is being printed in the console.

    "use" is set to the key 'e' in the project settings. I even tried using GetKeyDown(KeyCode.E); and I got the same results. Any kind of help is appreciated
     
  2. MartinMa_

    MartinMa_

    Joined:
    Jan 3, 2021
    Posts:
    455
    Last edited: Jul 25, 2021
  3. Kerdar

    Kerdar

    Joined:
    Jan 11, 2021
    Posts:
    8
    Code (CSharp):
    1.  using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.SceneManagement;
    5. public class OnTriggerLoadLevel : MonoBehaviour
    6. {
    7. public GameObject guiObject;
    8. void Start()
    9. {
    10. guiObject.SetActive(false); //setting the gui element to deactivated from the beginning
    11. }
    12. void OnTriggerEnter2D (Collider2D Player)
    13. {
    14. if (Player.gameObject.tag == "Player")
    15. {
    16. guiObject.SetActive(true); //when the collision happens, the gui element gets activated and shows "press [E] to enter" on the screen
    17. if (Input.GetButton("use")) //with the collision active, when 'E' is pressed scene with index 1 will load
    18. {
    19. SceneManager.LoadScene(1); //load scene with index 1 in the build settings
    20. }
    21. }
    22. }
    23. void OnTriggerExit2D() //when the collision stops, the gui element gets deactivated
    24. {
    25. guiObject.SetActive(false);
    26. }
    27. }
    I didn't know about this feature thanks for the headsup.
     
  4. MartinMa_

    MartinMa_

    Joined:
    Jan 3, 2021
    Posts:
    455
    Anything related to Input should be in Update method, not in start
    With your code you listening for input only on 1st frame of your game and on frame when your player enter collision.
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class ExampleClass : MonoBehaviour
    5. {
    6.     void Update()
    7.     {
    8.         if (Input.GetKeyDown(KeyCode.Space))
    9.         {
    10.             print("space key was pressed");
    11.         }
    12.     }
    13. }
    https://docs.unity3d.com/ScriptReference/Input.GetKeyDown.html
     
  5. Kerdar

    Kerdar

    Joined:
    Jan 11, 2021
    Posts:
    8
    There is no input in the start method. I am just setting the UI element to false so it doesn't show on the screen on launch. the input is in the OnTriggerEnter2D function at line 17.
     
  6. MartinMa_

    MartinMa_

    Joined:
    Jan 3, 2021
    Posts:
    455
    ye i edited my reply so you listening for input only on frame when collision start,you should listen for input in Update
     
  7. Kerdar

    Kerdar

    Joined:
    Jan 11, 2021
    Posts:
    8
    ah alright I get what you mean now, so i should be calling OnTriggerEnter() inside the update method am I correct?
     
  8. MartinMa_

    MartinMa_

    Joined:
    Jan 3, 2021
    Posts:
    455
    Try this :
    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.SceneManagement;
    3.  
    4.  
    5. //This script you put on your player.
    6. public class Player : MonoBehaviour
    7.     {
    8.     private void OnCollisionStay(Collision collision)
    9.         {
    10.         if(collision.gameObject.GetComponent<Door>() != null)
    11.             {
    12.             if(Input.GetKeyDown(KeyCode.E))
    13.                 {
    14.                 collision.gameObject.GetComponent<Door>().OpenDoor();
    15.                 }
    16.  
    17.             }
    18.         }
    19.     }
    20. //This script you attach on every door gameobject in scene, this gameobject will have child of your gui what you use set in inspector.I recommand you to use prefab for it.
    21. public class Door : MonoBehaviour
    22.     {
    23.     public GameObject doorGui;
    24.     bool guiDisplayed = false;
    25.  
    26.  
    27.     void Start()
    28.         {
    29.         doorGui.SetActive(false);
    30. guiDisplayed =false;
    31.         }
    32.  
    33.     public void OpenDoor()
    34.         {
    35.         SceneManager.LoadScene("Anything you want");
    36.         }
    37.  
    38.     private void OnCollisionEnter(Collision collision)
    39.         {
    40.  
    41.         if(collision.gameObject.GetComponent<Player>() != null)
    42.             {
    43.             doorGui.SetActive(true);
    44.             guiDisplayed = true;
    45.             }
    46.  
    47.         }
    48.     private void OnCollisionExit(Collision collision)
    49.         {
    50.         if(collision.gameObject.GetComponent<Player>() != null)
    51.             {
    52.             doorGui.SetActive(false);
    53.             guiDisplayed = false;
    54.             }
    55.         }
    56.     private void OnCollisionStay(Collision collision)
    57.         {
    58.         if(collision.gameObject.GetComponent<Player>() != null && !guiDisplayed)
    59.             {
    60.             doorGui.SetActive(true);
    61.             guiDisplayed = true;
    62.             }
    63.         }
    64.     }
    It is better to use OnCollisionStay because it is called every frame.
     
    Kerdar likes this.
  9. Kerdar

    Kerdar

    Joined:
    Jan 11, 2021
    Posts:
    8
    Thank you for the help, I really appreciate it