Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/unity3d/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 我希望我的玩家在触摸多个不同标签的物体时死亡_C#_Unity3d - Fatal编程技术网

C# 我希望我的玩家在触摸多个不同标签的物体时死亡

C# 我希望我的玩家在触摸多个不同标签的物体时死亡,c#,unity3d,C#,Unity3d,当我的玩家用不同的标签触摸两个不同的游戏对象时,我怎么能让他死掉呢。当玩家触碰“敌人”标签和“地面”标签时,他应该死亡。另外,我没有尝试对地面对象使用相同的敌人标记,因为我已经在对我的其他脚本使用“敌人”标记 使用系统集合; 使用System.Collections.Generic; 使用UnityEngine; 公共类:单一行为 { public float playerSpeed;//允许我们以统一的方式改变速度 公共矢量2跳跃高度; 公共bool isDead=false; 私有刚体2d

当我的玩家用不同的标签触摸两个不同的游戏对象时,我怎么能让他死掉呢。当玩家触碰“敌人”标签和“地面”标签时,他应该死亡。另外,我没有尝试对地面对象使用相同的敌人标记,因为我已经在对我的其他脚本使用“敌人”标记

使用系统集合;
使用System.Collections.Generic;
使用UnityEngine;
公共类:单一行为
{
public float playerSpeed;//允许我们以统一的方式改变速度
公共矢量2跳跃高度;
公共bool isDead=false;
私有刚体2d rb2d;
私人评分总经理;
void Start()
{
rb2d=GetComponent();
gm=GameObject.FindGameObjectWithTag(“gameMaster”).GetComponent();
}
无效更新()
{
if(isDead){return;}
transform.Translate(playerSpeed*Time.deltaTime,0f,0f);//使播放器运行
if(Input.GetMouseButtonDown(0)| | Input.GetKeyDown(KeyCode.Space))//使玩家跳跃
{
GetComponent().AddForce(跳线高度,ForceMode2D.Pulse);
}
}
专用空心OnCollisionInter2D(碰撞2D碰撞)
{
if(collision.gameObject.CompareTag(“ground”)//如果碰撞游戏对象上有地面标记,则返回true。
{
isDead=true;
rb2d.velocity=Vector2.0;
GameController.Instance.Die();
}
}
无效OnTriggerEnter2D(碰撞的R2D列)
{
如果(col.CompareTag(“硬币”))
{
销毁(游戏对象列);
gm.score+=1;
}
}

}
您可以使用以下方法,当敌人| | Gound标记进入和退出时调用该方法

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

OnCollisionCenter将针对在该帧期间开始接触播放器的每个对象单独调用一次

您需要创建一种方法,通过多次调用来跟踪OnCollisionEnter在该点上接触您的播放器的对象组。一种方法是为要检查的每种类型的标记创建布尔值:

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();
    }
} 
在每个OnCollisionCenter的末尾,您将验证是否遇到了这两个标记。在LateUpdate中,您将标志重置为false,以便重新检查下一帧


作为旁注,此解决方案的可扩展性不强。您可能希望使用层(LayerMask)和一点布尔逻辑,允许您在一个操作中比较多个类别。但那是另一个问题。

你好,为什么不这样做呢

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语句的较短版本。

我认为您可能问错了问题,您的意思是,如果玩家撞到地面或敌人,而不是同时撞到地面或敌人,他将死亡。一个简单的解决方法是按照尼古拉的建议做一个小改动:

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

只有当对象同时具有
地面
标记和
敌人
标记时,此脚本才会起作用。我尝试了,但它不起作用,我的玩家在接触敌人后仍然活着,我应该重新编写脚本吗?(我的敌人有敌人的标签!)没错,是我的错。“我对我的答案进行了编辑,使之与这个问题相对应。”尼古拉。在看到您对我的答案的评论后进行反思,您的解决方案将遇到相同的问题:对象将需要在同一帧中进入碰撞(不太可能)。如果(敌人和地面),你需要移动条件
if{…
into
Update
@kevernicus这是不会发生的。一旦有东西与玩家发生碰撞,特定的bool将变为活动状态,并在其游戏对象与玩家发生碰撞时保持活动状态。因此,如果玩家大部分时间与地面标签发生碰撞,无论何时与敌人发生碰撞,然后
if(敌人和地面)
将是正确的,因此它将满足问题的需要。关于
更新
,没有必要在每一帧上检查该条件。对我来说,这被认为是一种不好的做法,相反,我的方法是只在游戏对象发生碰撞时检查该条件。可能会在上面的代码中添加一些Debug.log以确保碰撞Enter2D确实被调用了,而且对象有正确的标记。@kevernicus这很完美,只是你不应该在后期更新中设置bools,因为这样这两个将永远不会是真的,也许idk。我还没有测试过,但我猜。当然,如果问问题的人只想在两个标记与玩家发生冲突时设置bools。@NikolaG。我明白你的意思。这个解决方案是可行的,但两个物体在同一帧中进入碰撞的可能性很小(特别是当玩家已经停飞时).我修改了代码,改为使用
OnCollisionStay2D
它不工作,给我3个错误,我应该在顶部添加任何Unity系统吗?嗯,您没有更改“此处的标记吗”字符串?您应该将其更改为您想要碰撞的对象的标记。如果不是这样,请说明3个错误。也很抱歉回答太晚。事实上,这是有效的。我还更新了我的原始答案,以便它涵盖了当您只需要两个游戏对象与玩家发生碰撞时的情况。答案基于kevernicu让我们来回答这个问题。