首页 > 解决方案 > 只发生在 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);

标签: c#unity3d

解决方案


这看起来很危险

if(bounds.Contains(newPos) && t) //meaning not 200 so it is there
{
    spawnTier (newPos, t);
}

您依靠它来退出 while 循环,但如果条件从未发生过,那么您就被卡住了。鉴于它需要某种界限,可能在平台上您会遇到这种情况永远不会发生的情况。或者你的层级用完了,并且永远阻止进入这部分代码

如果你不产生任何东西来确保你脱离循环,我认为你需要一个 else 子句。


推荐阅读