2017-02-07 4 views
2

Мне нужна помощь с функцией, которую я реализую для игры, сделанной в Unity 2D. Игрок должен взять ключ, чтобы открыть дверь (возможно, показывая анимацию), и когда игрок идет к этой двери, если у него есть ключ, он автоматически перейдет на следующий уровень. Мне нужна помощь, потому что дверь не позволяет перейти на следующий уровень.Перейти на следующий уровень, когда Key захвачен Player Unity 2d

Вот ключ код/​​скрипт:

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); 
    } 

} 

Вот ДВЕРЬ код/​​скрипт:

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); 

    } 


} 

код работает, но когда игрок идет перед дверью, он не переходя на следующий уровень. Любая помощь или подсказка оценены. Приветствия

+0

Вы пробовали 'GameObject.Find (« KeyDoor »). GetComponent () .SendMessage (« HitKey »);'? Или просто «GameObject.Find» («KeyDoor»). GetComponent () .key = true; ' –

+0

@ m.rogalski Я поставил этот GameObject.Find (« KeyDoor »). GetComponent по ключевому скрипту, но все еще не работает , –

+0

Вы уверены, что у всех 'GameObject' есть свои '' Collider 's прилагается и работает? –

ответ

1

Убедитесь, что игрок должен иметь Rigidbody2D и Collider2D и дверь имеет Collider2D компонент

Если ваши двери Collider2D триггер вы должны использовать аннулируются OnTriggerEnter2D(Collider2D other).

Другой проблемой может быть то, что «Уровень 2» не добавлен в ваши настройки сборки, убедитесь, что он добавлен в список уровня.

Отвечая на Ваш последний комментарий, как это казалось проблема заключалась в том, что Collider2D на двери, вы можете сделать это во многих отношениях, самый простой способ заключается в следующем:

Добавить публичную переменную строку с именем nextLevelName в вашем Дверной скрипт, затем при вызове LoadLevel используйте эту переменную. Вы можете изменить значение от инспектора на каждом уровне. Проблема заключается в том, что если вы перестраиваете уровни, вам нужно изменить строки на каждом уровне.

Лучшее решение в этом случае это одна:

int currentLevelNum = SceneManager.GetActiveScene().buildIndex; 
SceneManager.LoadScene(currentLevelNum+1); 

Таким образом, если у вас есть уровни, чтобы в настройках сборки вам не нужно делать что-нибудь еще.

+0

Да, но дверь с Rigidbody2D падает, даже если есть коллайдер box 2D как земля для физики. –

+0

Дверь не нуждается в жестком корпусе, если у игрока есть один. –

+0

@GunnarB. Дверь падает, когда я флаг «Триггер» на коллайдере 2D. –

1

Прежде всего, вы должны изменить Application.LoadLevel на SceneManager.LoadScene. Первый из них устарел в новых версиях единства.

Во-вторых вы должны убедиться, что ваши сцены на самом деле зарегистрировано в Файл -> BuildSettings и параметр вы передаете LoadScene спичек либо индекса в этом списке или имя в виде строки.

+0

В скрипте двери я хотел бы загрузить следующий уровень по-другому, потому что, как я писал, это непросто. Это означает, что мне нужно создать сценарий для двери на каждом уровне. Я бы хотел, чтобы сцена загружалась, хотя частная или общедоступная строка, которую я буду редактировать в каждой сцене. –

+0

Конечно, вы можете использовать открытую строку (или int), чтобы установить следующий уровень для двери. Вам просто нужно убедиться, что он соответствует списку настроек сборки. –

3

Прежде всего, вы пропустили одну вещь:

является Component на основе двигателя

Это означает, что вы должны сделать взаимодействие между Component с, не GameObject с.

В вашем скрипте есть поле publicpublic bool key, которое не должно быть доступно снаружи.Но если вы ищете простой и неправильный ответ, что будет работать, то вы можете просто заменить эту строку:

GameObject.Find("KeyDoor").SendMessage("HitKey"); 

В этом одно:

GameObject.Find("KeyDoor").GetComponent<DoorScript>().key = true; 

В этом случае вы будете в конечном итоге с грязным кодом и нестабильной игрой. То, что я могу вам порекомендовать в качестве хорошей альтернативы, - это немного переписать свою логику.

Вместо того, чтобы сделать MonoBehaviour, который не нужен, вы можете просто создать 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); 
    } 
} 

Теперь прикрепите в Component сек список ваших Player «ы и в вашей двери скриптом сделать:

void OnCollisionEnter2D (Collision2D other) 
{ 
    if(other.GetComponent<KeyComponent>() != null && other.GetComponent<KeyComponent>().PickedUp) 
    { 
     SceneManager.LoadScene(2); 
    } 
} 

Теперь осталось только обновить PlayerMonoBehaviour и добавить простую проверку:

void OnCollisionEnter2D(Collision2D other) 
{ 
    if(other.tag == "TAG_FOR_KEY") 
     GetComponent<DoorScript>().PickUp(); 
} 

Теперь вы взаимодействуете с Component s, а не GameObject, которые требуют меньше усилий, изменяя некоторые скрипты.

+0

Wow man, спасибо. Это очень полезная альтернатива MonoBehaviour –

Смежные вопросы