我需要一些帮助来实现我在Unity 2D中制作的游戏的功能。 玩家必须拿一把钥匙才能打开一扇门(可能会显示一个动画),当玩家拿到钥匙进入门前时,他会自动进入下一关。 我需要帮助,因为门不会放到一个新的水平。
这是KEY代码/脚本:
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);
}
}
代码有效,但当玩家走到门前时,他没有进入下一级别。 任何帮助或提示赞赏。 干杯
答案 0 :(得分:3)
首先,你错过了一件事:
unity是基于Component
的引擎
这意味着您应该在Component
之间进行互动,而不是GameObject
s。
在您的脚本中,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);
}
}
现在将此附加到您的Player
Component
列表中并在您的门脚本中执行:
void OnCollisionEnter2D (Collision2D other)
{
if(other.GetComponent<KeyComponent>() != null && other.GetComponent<KeyComponent>().PickedUp)
{
SceneManager.LoadScene(2);
}
}
现在只剩下更新Player
&#39; MonoBehaviour
并添加简单的碰撞检查:
void OnCollisionEnter2D(Collision2D other)
{
if(other.tag == "TAG_FOR_KEY")
GetComponent<DoorScript>().PickUp();
}
现在您正在与Component
进行交互而不是GameObject
,这样就可以减少更改某些脚本的工作量。
答案 1 :(得分:1)
确保您的播放器需要Rigidbody2D
和Collider2D
并且门上有Collider2D
组件
如果您的门Collider2D
是触发器,则必须使用void OnTriggerEnter2D(Collider2D other)
。
另一个问题可能是“级别2”未添加到您的构建设置中,请确保将其添加到级别列表中。
回答你的上一条评论似乎问题是门上的Collider2D
,你可以用很多方式做到这一点,最简单的方法就是这样:
在Door的脚本中添加一个名为nextLevelName
的公共字符串变量,然后在调用LoadLevel
时,使用此变量。您可以在每个级别更改检查器中的值。这样做的问题是,如果重新排列级别,则需要更改每个级别的字符串。
在这种情况下,最好的解决方案是:
int currentLevelNum = SceneManager.GetActiveScene().buildIndex;
SceneManager.LoadScene(currentLevelNum+1);
这样,如果您在构建设置中按顺序排列了级别,则无需执行任何其他操作。
答案 2 :(得分:1)
首先,您应该将Application.LoadLevel
更改为SceneManager.LoadScene
。第一个版本在统一的新版本中已经过时了。
其次,你需要确保你的场景实际上是在文件 - &gt;中注册的。 BuildSettings 和传递给LoadScene
的参数匹配该列表中的索引或名称为字符串。