2

我需要一些关于我为 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);

    }


}

代码有效,但是当玩家走到门前时,他并没有传递到下一个级别。任何帮助或提示表示赞赏。干杯

4

3 回答 3

4

首先,您缺少一件事:

基于Component引擎

这意味着您应该在Components 之间进行交互,而不是GameObjects。

在您的脚本中有一个不应从外部访问的public字段。public 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);
    }
}

现在将此附加到您PlayerComponent列表中,并在您的门脚本中执行以下操作:

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

现在您正在与Components 进行交互,而不是GameObject在更改某些脚本时需要更少的精力。

于 2017-02-07T15:35:47.747 回答
1

首先,您应该更改Application.LoadLevelSceneManager.LoadScene. 第一个在较新版本的统一中已过时。

其次,您需要确保您的场景实际上已在File -> BuildSettings中注册,并且您传递给的参数LoadScene与该列表中的索引或字符串形式的名称匹配。

于 2017-02-07T15:06:20.990 回答
1

确保您的播放器需要有 aRigidbody2D和 aCollider2D并且门有一个Collider2D组件

如果您的门Collider2D是触发器,则必须使用 void OnTriggerEnter2D(Collider2D other)

另一个问题可能是“级别 2”没有添加到您的构建设置中,请确保将其添加到级别列表中。

回答您的最后一条评论,因为问题似乎是Collider2D在门上,您可以通过多种方式做到这一点,最简单的方法是:

nextLevelName添加一个在 Door 脚本中调用的公共字符串变量,然后在调用LoadLevel时使用此变量。您可以在每个级别的检查器中更改值。这样做的问题是,如果您重新排列级别,那么您需要更改每个级别中的字符串。

在这种情况下,最好的解决方案是这个:

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

这样,如果您在构建设置中按顺序排列关卡,则无需执行任何其他操作。

于 2017-02-07T14:32:53.307 回答