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