c# - 只发生在 iPhone 上而不发生在编辑器中的无限循环在哪里?
问题描述
好的,我过去曾在设备/iphone上发生无限循环/冻结但在编辑器中没有发生这种情况 - 并且没有错误消息。没有崩溃只是冻结。
我已经运行了 Debug.Logs 并尝试了更多延迟,但我不知道是什么导致 iPhone 冻结/这里的一些无限循环。FPS也下降了,我检查了。
基本上,我尝试在平面上生成一定数量的对象,这些对象会随着生成过程的发生而增长,并且更多的对象会添加到场景中。一旦超过对象的最大上限,生成过程就会停止。
这是我这样做的方法,在编辑器中效果很好 -
第1部分:
if(anchorManager.CloneNumberGet() > 0) //first was placed
{
hasTriedSpawn = true;
//StartCoroutine (spawnAllTiers (30));
TriggerTierSpawn(); //sets off whole thing
}
第2部分:
public void TriggerTierSpawn()
{
if (GameController.trackingReady) {
World w = worlds[currentWorld];
int max = w.numTiers + 10;
if (tiersSpawned.Length < max && AreThereEmptyPlanes () && max <= GameController.spawnLimit) {
planesFilled.ToList ().Sort ((pair1, pair2) => pair1.Value.CompareTo (pair2.Value));
//orderedPlanes = planesFilled.Keys.ToList ();
print ("Running this loop");
foreach (KeyValuePair<GameObject, float> entry in planesFilled) {
GameObject plane = entry.Key;
//print ("P: "+plane);
if (CheckForEmptySpace (plane.GetComponentInChildren<BoxCollider> ().bounds) != absurdVector3 && plane.GetComponentInChildren<BoxCollider> ().bounds
!= null && tiersSpawned.Length < max) {
StartCoroutine (spawnAllTiers (max, plane.GetComponentInChildren<BoxCollider> ().bounds));
}
//put a wait here
}
} else if (tiersSpawned.Length < max) {
print ("Wait for more planes");
} else {
//print ("REACHED MAX: "+max+" Num tiers: "+tiersSpawned.Length);
}
}
}
public Vector3 CheckForEmptySpace (Bounds bounds)
{
float sphereRadius = tierDist;
Vector3 startingPos = new Vector3 (UnityEngine.Random.Range(bounds.min.x, bounds.max.x), bounds.min.y, UnityEngine.Random.Range(bounds.min.z, bounds.max.z));
// Loop, until empty adjacent space is found
var spawnPos = startingPos;
while ( true )
{
if (!(Physics.CheckSphere(spawnPos, sphereRadius, 1 << 0)) ) // Check if area is empty
return spawnPos; // Return location
else
{
// Not empty, so gradually move position down. If we hit the boundary edge, move and start again from the opposite edge.
var shiftAmount = 0.5f;
spawnPos.z -= shiftAmount;
if ( spawnPos.z < bounds.min.z )
{
spawnPos.z = bounds.max.z;
spawnPos.x += shiftAmount;
if ( spawnPos.x > bounds.max.x )
spawnPos.x = bounds.min.x;
}
// If we reach back to a close radius of the starting point, then we didn't find any empty spots
var proximity = (spawnPos - startingPos).sqrMagnitude;
var range = shiftAmount-0.1; // Slight 0.1 buffer so it ignores our initial proximity to the start point
if ( proximity < range*range ) // Square the range
{
Debug.Log( "PLANE FULL - an empty location could not be found" ); //means plane is FULL
return absurdVector3;
}
}
}
}
第 3 部分:
public IEnumerator spawnAllTiers(int maxNum, Bounds bounds)
{
while (tiersSpawned.Length < maxNum) { //still has space
Tier t = getNextTier ();
//Vector3 newPos = new Vector3 (UnityEngine.Random.Range(GetGrid ().bounds.min.x, GetGrid ().bounds.max.x), GetGrid ().bounds.min.y, UnityEngine.Random.Range(GetGrid ().bounds.min.z, GetGrid ().bounds.max.z));
Vector3 newPos = CheckForEmptySpace (bounds);
if(bounds.Contains(newPos) && t) //meaning not 200 so it is there
{
spawnTier (newPos, t);
}
platformsSpawned = GameObject.FindObjectsOfType<Platform> ();
tiersSpawned = GameObject.FindObjectsOfType<Tier> ();
yield return new WaitForSeconds (0.3f); //increase this if have iphone problem
//START NEW --------------------
if (CheckForEmptySpace (bounds) == absurdVector3 && tiersSpawned.Length < maxNum)
{
break;
}
}
//maybe check for num times trying, or if size of all spawned tiers is greater than area approx
}
Tier getNextTier()
{
Tier p = null;
int j = UnityEngine.Random.Range (0, worlds [currentWorld].tiers.Count);
p = worlds [currentWorld].tiers[j];
return p;
}
//SPAWN NEXT TIER
public void spawnTier(Vector3 position, Tier t) //if run out of plats THEN we spawn up like tree house
{
print ("SUCCESS - spawn "+position+"SPHERE: "+Physics.CheckSphere(position, tierDist, 1 << 0));
Instantiate (t, position, Quaternion.identity);
anchorManager.AddAnchor(t.gameObject);
}
我不知道在这里做什么。理想情况下,我只需要填满这些平面,如果尚未达到最大数量的对象,因为它们已经存在。
编辑-尝试:
if(bounds.Contains(newPos) && t) //meaning not 200 so it is there
{
spawnTier (newPos, t);
} else {
break;
}
并且只是spawnTier (newPos, t);
解决方案
这看起来很危险
if(bounds.Contains(newPos) && t) //meaning not 200 so it is there
{
spawnTier (newPos, t);
}
您依靠它来退出 while 循环,但如果条件从未发生过,那么您就被卡住了。鉴于它需要某种界限,可能在平台上您会遇到这种情况永远不会发生的情况。或者你的层级用完了,并且永远阻止进入这部分代码
如果你不产生任何东西来确保你脱离循环,我认为你需要一个 else 子句。
推荐阅读
- excel - VBA 在 Word 对象上使用 Excel 版本的查找?
- javascript - 通过正文单击打开窗口弹出器
- java - 无法使用 @AllArgsConstructor 访问构造函数,但可以使用 @RequiredArgsConstructor
- python - 使用elasticsearch-dsl的delete方式时版本冲突
- c - 使用 fread 函数读取二进制文件的问题
- python - 如何将来自 for 循环的值更新为嵌套字典?
- html - 在 VS Code 中,如何选择打开 HTML 标签、关闭 HTML 标签以及介于两者之间的所有内容?
- r - 创建 NA 的日期
- spring-boot - 与springboot的Keycloak版本兼容性问题
- javascript - 如何将函数存储到存储变量中?