仅检测一次碰撞/碰撞 [英] Detect collision/colliding only once

查看:102
本文介绍了仅检测一次碰撞/碰撞的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个物体向另一个物体移动并与之发生物理碰撞,我希望碰撞/碰撞事件仅发生一次.我尝试使用bool,但是它没有按预期工作.看来我做错了.

I have an object that moves towards another object and physically collides with it, I want that collision/colliding event to happen only once. I tried using a bool but it didn't work as intended. It seems that I'm doing something wrong.

bool doDamage = true;
void OnCollisionEnter2D(Collision2D other)
{
    if (other.gameObject.tag == "Target" && doDamage)
    {
        doDamage = false;
        // damage code
    }
}

void OnCollisionExit2D(Collision2D other)
{
    if (other.gameObject.tag == "Target")
    {
        doDamage = true;
    }
}

即使两个对象仍处于接触状态,我也希望损坏代码"仅运行一次.此脚本仅分配给1个对象,不能同时分配给两个对象.

I want the "damage code" to run only once, even if the 2 objects are still in contact. This script is only assigned to 1 object, not both.

推荐答案

我不知道解释您的代码为何不起作用的最简单方法,但我会尝试.

I don't know the easiest way to explain why your code is not working but I will try.

您有两个GameObject:

You have two GameObjects:

    具有doDamage变量的
  1. GameObject A .

GameObject B doDamage变量.

GameObject A GameObject B 碰撞时:

A .OnCollisionEnter2D函数在 GameObject A 上调用. 因为doDamage为true,所以执行if(other.gameObject.tag == "Target" && doDamage).

A.The OnCollisionEnter2D function is called on GameObject A. if(other.gameObject.tag == "Target" && doDamage) executes because doDamage is true.

B .然后将 GameObject A 中的doDamage变量设置为false.

B.The doDamage variable from GameObject A is then set to false.

这不会影响 GameObject B 中的doDamage变量.

This does not affect the doDamage variable from GameObject B.

然后

C .OnCollisionEnter2D函数在 GameObject B 上调用. 因为doDamage为true,所以执行if(other.gameObject.tag == "Target" && doDamage).

C.The OnCollisionEnter2D function is called on GameObject B. if(other.gameObject.tag == "Target" && doDamage) executes because doDamage is true.

D .然后将 GameObject B 中的doDamage变量设置为false.

D.The doDamage variable from GameObject B is then set to false.

这两个伤害代码都将运行,因为在每个OnCollisionEnter2D调用中doDamage始终为true.您目前所做的只是影响每个个人脚本中的doDamage变量.

Both your damage code will run because doDamage is always true in each OnCollisionEnter2D call. What you are currently doing is only affecting doDamage variable in each individual script.

您当前正在做什么:

local/this 脚本中将doDamage设置为false,同时还要检查是否设置了 local/this doDamage.

Setting doDamage in the local/this script to false while also checking if local/this doDamage is set or not.

您需要做什么:

other 脚本中将doDamage设置为false,但阅读 local/this doDamage来检查是否已设置.

Set doDamage in the other script to false but read the local/this doDamage to check if it is set or not.

它应该是这样的:

public class DamageStatus : MonoBehaviour
{
    bool detectedBefore = false;

    void OnCollisionEnter2D(Collision2D other)
    {
        if (other.gameObject.CompareTag("Target"))
        {
            //Exit if we have already done some damage
            if (detectedBefore)
            {
                return;
            }

            //Set the other detectedBefore variable to true
            DamageStatus dmStat = other.gameObject.GetComponent<DamageStatus>();
            if (dmStat)
            {
                dmStat.detectedBefore = true;
            }

            // Put damage/or code to run once below

        }
    }

    void OnCollisionExit2D(Collision2D other)
    {
        if (other.gameObject.tag == "Target")
        {
            //Reset on exit?
            detectedBefore = false;
        }
    }
}

这篇关于仅检测一次碰撞/碰撞的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆