八球游戏刚体停球检测问题:如何判断所有球速度低于0.1?
八球台球游戏:检测所有球停止运动的问题解决
我正在开发一款八球台球游戏,需要检测台面上所有球何时停止运动。我尝试使用以下代码,但已停止的球的计数(Balls_Stopped)不断增长到极大数值,而实际数值应不超过16。
原代码:
IEnumerator CheckObjectsHaveStopped() { bool allSleeping = false; Rigidbody[] GOS = FindObjectsOfType(typeof(Rigidbody)) as Rigidbody[]; while (!allSleeping) { allSleeping = true; foreach (Rigidbody GO in GOS) { if (GO.velocity.magnitude <= 0.1) { Balls_Stopped += 1; Debug.Log("Balls Stopped = " + Balls_Stopped); yield return null; } } } if (Balls_Stopped == Balls_Left) { print("All objects sleeping"); //Do something here } }
问题根源
- 计数逻辑错误:每次循环遍历刚体时,只要球满足速度条件就累加
Balls_Stopped,同一个球每帧都会被重复计数,导致数值疯涨。 - 循环逻辑漏洞:
allSleeping初始设为true,但没有处理“球未停止”的情况——只要有一个球还在动,应该把allSleeping设回false,否则循环会卡死。 - 帧暂停位置错误:
yield return null放在foreach内部,会导致每次检测到一个停止的球就暂停一帧,无法一次性完成所有球的状态检测。
修正方案
方案1:每帧重新统计停止的球数(推荐)
这种方式直接每帧计算当前停止的球数量,避免累加错误,同时兼顾旋转状态的检测:
IEnumerator CheckObjectsHaveStopped() { Rigidbody[] allBalls = FindObjectsOfType<Rigidbody>(); while (true) { int currentStoppedCount = 0; bool allStopped = true; foreach (Rigidbody ball in allBalls) { // 同时检测线速度和角速度,避免球旋转但不移动的误判 if (ball.velocity.magnitude <= 0.1f && ball.angularVelocity.magnitude <= 0.1f) { currentStoppedCount++; } else { allStopped = false; } } Debug.Log("当前停止的球数: " + currentStoppedCount); if (allStopped) { print("所有球已停止运动"); // 在这里添加球停止后的逻辑,比如允许玩家再次击球 break; } yield return null; // 每帧检测一次 } }
方案2:用集合标记已停止的球(适合跟踪单个球状态)
如果需要单独记录哪些球已经停止,可以用HashSet来标记,避免重复计数:
HashSet<Rigidbody> stoppedBalls = new HashSet<Rigidbody>(); IEnumerator CheckObjectsHaveStopped() { Rigidbody[] allBalls = FindObjectsOfType<Rigidbody>(); while (stoppedBalls.Count < allBalls.Length) { stoppedBalls.Clear(); // 每帧重新标记当前停止的球 foreach (Rigidbody ball in allBalls) { if (ball.velocity.magnitude <= 0.1f && ball.angularVelocity.magnitude <= 0.1f) { stoppedBalls.Add(ball); } } Debug.Log("当前停止的球数: " + stoppedBalls.Count); if (stoppedBalls.Count == allBalls.Length) { print("所有球已停止运动"); // 执行后续逻辑 break; } yield return null; } stoppedBalls.Clear(); // 重置集合,方便下次检测使用 }
内容的提问来源于stack exchange,提问作者Coder
相关产品推荐
相关产品推荐

