【问题标题】:Go to next level when Key is grabbed by Player Unity 2d当玩家 Unity 2d 抓住钥匙时进入下一个级别
【发布时间】:2017-02-07 23:54:09
【问题描述】:

我需要一些关于我正在为使用 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);
    }

}

这是 DOOR 代码/脚本:

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

    }


}

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

【问题讨论】:

  • 你试过GameObject.Find("KeyDoor").GetComponent&lt;DoorScript&gt;().SendMessage("HitKey");吗?或者更简单的GameObject.Find("KeyDoor").GetComponent&lt;DoorScript&gt;().key = true;
  • @m.rogalski 我把这个 GameObject.Find("KeyDoor").GetComponent 放在关键脚本上,但还是不行。
  • 你确定所有的GameObjects 都有他们的Colliders 连接并且工作吗?
  • @m.rogalski 现在工作了,但我有另一个问题,进入门脚本我想以另一种方式加载下一个级别,因为我写的方式并不容易。这意味着我需要为每个级别的门制作脚本。

标签: c# unity3d unity5 unity2d


【解决方案1】:

首先,您缺少一件事:

是基于 Component 的引擎

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

在您的脚本中有一个 public 字段 public bool key 不应从外部访问。但是,如果您正在寻找简单且 错误 将起作用 的答案,那么您可以替换这一行:

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

进入这个:

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

在这种情况下,您最终会得到混乱的代码和不稳定的游戏。我可以向您推荐的一个不错的选择是稍微重写您的逻辑。

您可以创建一个Component,而不是创建一个不需要的MonoBehaviour

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

现在将此附加到您的PlayerComponents 列表中,并在您的门脚本中执行:

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 进行交互,因此更改某些脚本所需的工作量更少。

【讨论】:

  • 哇,谢谢。这是 MonoBehaviour 的一个非常有用的替代方案
【解决方案2】:

首先,您应该将Application.LoadLevel 更改为SceneManager.LoadScene。第一个在较新版本的 unity 中已过时。

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

【讨论】:

  • 进入门脚本我想以另一种方式加载下一个级别,因为我写的方式并不容易。这意味着我需要为每个级别的门制作脚本。我想将场景设置为通过我将在每个场景中编辑的私有或公共字符串加载。
  • 当然,您可以使用公共字符串(或 int)来设置门的下一级。您只需要确保匹配构建设置列表。
【解决方案3】:

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

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

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

回答您的最后一条评论,因为问题似乎是门上的Collider2D,您可以通过多种方式进行此操作,最简单的方法是:

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

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

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

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

【讨论】:

  • 是的,但是带有 Rigidbody2D 的门正在倒塌,即使有一个 2D 盒式对撞机作为物理基础。
  • 如果玩家有刚体,门就不需要刚体了。
  • @GunnarB。当我在 Box Collider 2D 上标记 Is Trigger 时,门会倒下。
  • @Juan Bayona Beriso 我解决了问题,现在一切正常。你能帮我吗?进入门脚本我想以另一种方式加载下一个级别,因为我写的方式并不容易。这意味着我需要为每个级别的门制作脚本
  • @Juan Bayona Beriso 您可以检查我编辑的代码,看看是否可以?谢谢老兄的帮助
猜你喜欢
  • 2016-09-11
  • 1970-01-01
  • 1970-01-01
  • 2022-10-15
  • 1970-01-01
  • 1970-01-01
  • 2020-09-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多