仅检测碰撞/碰撞一次

我有一个物体向另一个物体移动并与物体碰撞,我希望碰撞/碰撞事件只发生一次。 我尝试使用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个对象,而不是两个。

我不知道最简单的方法来解释为什么你的代码不起作用但我会尝试。

你有两个游戏对象:

  1. 具有doDamage变量的doDamage

  2. 带有doDamage变量的doDamage

GameObject AGameObject B发生碰撞时:

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

B.然后将来自doDamage A的 doDamage变量设置为false

这不会影响doDamage BdoDamage变量。

然后

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错误。 前者更有可能。