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
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);
}
}
I didnāt know about this feature thanks for the headsup.
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.
using UnityEngine;
using System.Collections;
public class ExampleClass : MonoBehaviour
{
void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
print("space key was pressed");
}
}
}
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.
using UnityEngine;
using UnityEngine.SceneManagement;
//This script you put on your player.
public class Player : MonoBehaviour
{
private void OnCollisionStay(Collision collision)
{
if(collision.gameObject.GetComponent<Door>() != null)
{
if(Input.GetKeyDown(KeyCode.E))
{
collision.gameObject.GetComponent<Door>().OpenDoor();
}
}
}
}
//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.
public class Door : MonoBehaviour
{
public GameObject doorGui;
bool guiDisplayed = false;
void Start()
{
doorGui.SetActive(false);
guiDisplayed =false;
}
public void OpenDoor()
{
SceneManager.LoadScene("Anything you want");
}
private void OnCollisionEnter(Collision collision)
{
if(collision.gameObject.GetComponent<Player>() != null)
{
doorGui.SetActive(true);
guiDisplayed = true;
}
}
private void OnCollisionExit(Collision collision)
{
if(collision.gameObject.GetComponent<Player>() != null)
{
doorGui.SetActive(false);
guiDisplayed = false;
}
}
private void OnCollisionStay(Collision collision)
{
if(collision.gameObject.GetComponent<Player>() != null && !guiDisplayed)
{
doorGui.SetActive(true);
guiDisplayed = true;
}
}
}
It is better to use OnCollisionStay because it is called every frame.