我希望玩家触摸带有不同标签的多个对象时死亡

时间:2019-05-03 22:38:49

标签: c# unity3d

当我的玩家触摸带有不同标签的两个不同游戏对象时,如何使他死亡。玩家触摸“敌人”标签和“地面”标签时应该死亡。另外,我不想在地面物体上使用相同的敌人标签,因为我已经在其他脚本中使用了“敌人”标签。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Move2d : MonoBehaviour
{
    public float playerSpeed;  //allows us to be able to change speed in Unity
    public Vector2 jumpHeight;
    public bool isDead = false;
    private Rigidbody2D rb2d;
    private Score gm;

    void Start()
    {
        rb2d = GetComponent<Rigidbody2D>();
        gm = GameObject.FindGameObjectWithTag("gameMaster").GetComponent<Score>();
    }

    void Update()
    {
        if (isDead) { return; }
        transform.Translate(playerSpeed * Time.deltaTime, 0f, 0f);  //makes player run

        if (Input.GetMouseButtonDown(0) || Input.GetKeyDown(KeyCode.Space))  //makes player jump
        {
            GetComponent<Rigidbody2D>().AddForce(jumpHeight, ForceMode2D.Impulse);
        }
    }

    private void OnCollisionEnter2D(Collision2D collision)
    {
        if (collision.gameObject.CompareTag("ground")) // this will return true if the collision gameobject has ground tag on it.
        {
            isDead = true;
            rb2d.velocity = Vector2.zero;
            GameController.Instance.Die();
        }
    }

    void OnTriggerEnter2D(Collider2D col)
    {
        if( col.CompareTag("coin"))
        {
            Destroy(col.gameObject);
            gm.score += 1;
        }
    }
}

4 个答案:

答案 0 :(得分:1)

在该帧期间开始接触播放器的每个对象都会分别调用一次OnCollisionEnter。

您将需要创建一种方法来跟踪对OnCollision的多次调用输入此时接触您的播放器的对象组。一种方法是为要检查的每种标签类型创建一个布尔值:

private bool touchedGround = false;
private bool touchedEnemy = false;

private void LateUpdate() {
   touchedGround = false;
   touchedEnemy = false;
}

private void OnCollisionStay2D(Collision2D collision) {
    if (collision.gameObject.CompareTag("ground")) {
        touchedGround = true;
    }

    if (collision.gameObject.CompareTag("enemy")) {
        touchedEnemy = true;
    }

    if (touchedGround && touchedEnemy) {
       isDead = true;
       rb2d.velocity = Vector2.zero;
       GameController.Instance.Die();
    }
} 

在每个OnCollisionEnter的末尾,您将验证是否同时遇到了两个标签。在LateUpdate中,将标志重置为false,以便重新检查下一帧。

请注意,此解决方案不是很可扩展。您可能希望使用图层(LayerMask)和一些布尔逻辑,使您可以在一个操作中比较多个类别。但这将是一个不同的问题。

答案 1 :(得分:1)

我认为您可能会问错这个问题,这意味着玩家如果撞到地面或被敌人击中会死亡,而不是同时击中敌人。如Nikola建议的那样,进行了一个简单的修复,但做了一些小的更改:

private void OnCollisionEnter2D(Collision2D collision)
{
    if (collision.gameObject.CompareTag("ground") || collision.gameObject.CompareTag("enemy"))
    {
        isDead = true;
        rb2d.velocity = Vector2.zero;
        GameController.Instance.Die();
    }
}

答案 2 :(得分:0)

您可以使用以下方法,当敌人||时调用该方法。地标进入&&退出。

private bool enemy, ground;

private void OnCollisionEnter2D(Collision2D collision)
{
    if (collision.gameObject.CompareTag("Enemy"))
    {
        enemy = true;
    }

    if (collision.gameObject.CompareTag("Ground"))
    {
        ground = true;
    }

    if(enemy && ground)
    {
        Debug.Log("Enemy and Ground collision");
    }
}

private void OnCollisionExit2D(Collision2D collision)
{
    if (collision.gameObject.CompareTag("Enemy"))
    {
        enemy= false;
    }

    if (collision.gameObject.CompareTag("Ground"))
    {
        ground = false;
    }
}

答案 3 :(得分:0)

你好,为什么不这样做

private void OnCollisionEnter2D(Collision2D collision)
{
    switch (collision.gameobject.tag)
        case "tag_here"
           isDead = true;
           rb2d.velocity = Vector2.zero;
           GameController.Instance.Die();
           break;
       case "tag_here2"
           isDead = true;
           rb2d.velocity = Vector2.zero;
           GameController.Instance.Die();
           break;
       case "tag_here3"
           isDead = true;
           rb2d.velocity = Vector2.zero;
           GameController.Instance.Die();
           break;
       //Copy paste as long as you need more
    }

switch语句类似于if语句的较短版本。