Reputation: 97
I need some help with a feature I'm implementing for a game made in Unity 2D. The player must take a key in order to unlock a door (maybe showing an animation) and when the player go in front of that door if he has the key, he will automatically go to the next level. I need help, cause the door is not letting go to the next level.
Here is the KEY code/script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
public class KeyScript : MonoBehaviour {
//public AudioSource coinSoundEffect;
public AudioClip key1;
void Awake () {
//source = GetComponent<AudioSource>();
}
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
void OnCollisionEnter2D (Collision2D other) {
Debug.Log("Chiave Presa");
if(other.gameObject.tag =="Player")
GameObject.Find("KeyDoor").SendMessage("HitKey");
SoundManager2D.playOneShotSound(key1);
}
}
Here is the DOOR code/script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
public class DoorScript : MonoBehaviour {
public bool key = false;
public string nextLevelName;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
void HitKey (){
Debug.Log("La porta è sbloccata");
key = true;
Destroy (GameObject.Find ("Key"));
}
void OnCollisionEnter2D (Collision2D other){
if(other.gameObject.tag == "Player"){
if (key == true){
Application.LoadLevel(nextLevelName);
//Destroy(gameObject);
//GameObject.Find("Key").SendMessage("DestroyKey"); //If you also want to destroy the key
//GoToNextLevel ();
}
}
}
void OnTriggerEnter2D (Collision2D other)
{
Application.LoadLevel(nextLevelName);
}
public virtual void GoToNextLevel()
{
//loadingImage.SetActive(true);
Application.LoadLevel(nextLevelName);
}
}
The code works but when the player goes in front of the door, he is not passing to the next level. Any help or hint appreciated. Cheers
Upvotes: 2
Views: 1058
Reputation: 5920
First of all, you're missing one thing:
unity is Component
based engine
This means you should make interactions between Component
s, not GameObject
s.
In your script there's a public
field public bool key
which should not be accessible from the outside. But if you're looking for simple and wrong answer that will work then you can just replace this line :
GameObject.Find("KeyDoor").SendMessage("HitKey");
Into this one :
GameObject.Find("KeyDoor").GetComponent<DoorScript>().key = true;
In that case you'll end up with messy code and unstable game. What I can recommend to you as an good alternative is to rewrite your logic a bit.
Instead of making a MonoBehaviour
which is not needed you can just create a Component
:
public class KeyComponent : Component
{
[SerializeField]
AudioClip m_KeyPickupSound;
[SerializeField]
bool m_IsPickedUp;
public bool PickedUp
{
get { return m_IsPickedUp; }
}
public void PickUp()
{
m_IsPickedUp = true;
SoundManager2D.playOneShotSound(m_KeyPickupSound);
}
}
Now attach this into your Player
's Component
s list and in your door script do:
void OnCollisionEnter2D (Collision2D other)
{
if(other.GetComponent<KeyComponent>() != null && other.GetComponent<KeyComponent>().PickedUp)
{
SceneManager.LoadScene(2);
}
}
Now only thing left is to update your Player
's MonoBehaviour
and add simple collision check :
void OnCollisionEnter2D(Collision2D other)
{
if(other.tag == "TAG_FOR_KEY")
GetComponent<DoorScript>().PickUp();
}
Now you're interacting with Component
s and not GameObject
which then require less effort changing some scripts.
Upvotes: 4
Reputation: 727
Make sure your player needs to have a Rigidbody2D
and a Collider2D
and the door has a Collider2D
component
If your doors Collider2D
is a trigger you must use void OnTriggerEnter2D(Collider2D other)
.
Another problem may be that "Level 2" isn't added to your build settings, make sure that it is added to the level's list.
Answering your last comment as it seemed the problem was that the Collider2D
on the door, you can make this in a lot of ways, the easiest way is this:
Add a public string variable called nextLevelName
in your Door's script, then when calling LoadLevel
, use this variable. You can change the value from the inspector in each level. The problem with this is that if you rearrange the levels then you need to change the strings in each level.
The best solution in that case is this one:
int currentLevelNum = SceneManager.GetActiveScene().buildIndex;
SceneManager.LoadScene(currentLevelNum+1);
This way if you have your levels in order in your build settings you don't need to do anything else.
Upvotes: 1
Reputation: 2989
First off, you should change Application.LoadLevel
to SceneManager.LoadScene
. The first is obsolete in the newer versions of unity.
Second you need to make sure that your scenes are actually registered in File -> BuildSettings and the parameter you pass to LoadScene
matches either the index in that list or the name as string.
Upvotes: 1