仅检测碰撞/碰撞一次
我有一个物体向另一个物体移动并与物体碰撞,我希望碰撞/碰撞事件只发生一次。 我尝试使用bool
但它没有按预期工作。 看来我做错了什么。
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; } }
编辑:
我希望“损坏代码”只运行一次,即使这2个对象仍在接触。 此脚本仅分配给1个对象,而不是两个。
我不知道最简单的方法来解释为什么你的代码不起作用但我会尝试。
你有两个游戏对象:
-
具有
doDamage
变量的doDamage
-
带有
doDamage
变量的doDamage
当GameObject A与GameObject B发生碰撞时:
A.在 OnCollisionEnter2D
A上调用OnCollisionEnter2D
函数。 if(other.gameObject.tag == "Target" && doDamage)
执行因为doDamage
为true。
B.然后将来自doDamage
A的 doDamage
变量设置为false
。
这不会影响doDamage
B的doDamage
变量。
然后
C.在 OnCollisionEnter2D
B上调用OnCollisionEnter2D
函数。 if(other.gameObject.tag == "Target" && doDamage)
执行因为doDamage
为true。
D.然后将来自doDamage
B的 doDamage
变量设置为false
。
您的损坏代码都将运行,因为在每个OnCollisionEnter2D
调用中doDamage
始终为true。 您当前正在做的只是影响每个脚本中的doDamage
变量。
你目前在做什么 :
将local / this脚本中的doDamage
设置为false
同时还检查是否设置了local / this doDamage
。
你需要做什么 :
将另一个脚本中的doDamage
设置为false
但是读取本地/此 doDamage
以检查它是否已设置。
它应该是这样的:
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(); 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; } } }
如果要运行一段代码,请直接在要触发代码的回调事件中运行代码。
void OnCollisionEnter2D(Collision2D other) { DoSomeDamageTo(other.gameObject); }
这应该只在碰撞时触发一次。
如果你想要只发生一次(例如,如果持有脚本的对象再次击中某个东西),你需要一个标志来说明损坏已经完成:
bool hasHitSomething = false; void OnCollisionEnter2D(Collision2D other) { if (!hasHitSomething) { DoSomeDamageTo(other.gameObject); hasHitSomething = true; } }
我怀疑给出了你共享的代码,要么对象在引擎中多次碰撞(如果它们是实体和物理控制的话很可能),导致OnCollisionEnter
调用OnCollisionEnter
。 每次碰撞只应调用一次OnCollisionEnter
。 如果您正在观察它被多次调用,您实际上是在观察多次碰撞,或者您发现了一个模糊的Unity错误。 前者更有可能。