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