仅检测一次碰撞/碰撞 [英] Detect collision/colliding only once
问题描述
我有一个物体向另一个物体移动并与之发生物理碰撞,我希望碰撞/碰撞事件仅发生一次.我尝试使用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:
-
具有
-
GameObject A .
doDamage
变量的 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屋!