Unity - CheckSphere не работает? спавн зависает только на устройстве?

Я пытаюсь создать определенное количество кубов в постоянно меняющейся области (плоскость, ARKit) и НЕ перекрывать их. Я думаю, довольно просто, и у меня это работает в редакторе Unity так:

введите здесь описание изображения

Моя проблема заключается в развертывании на устройстве (iPhone), и все по-другому. Некоторые вещи не работают, и я не знаю почему - это относительно простой скрипт. Сначала я подумал, что CheckSphere не работает, что-то с другим масштабом, но вот как я пытаюсь получить пустое место:

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( "An empty location could not be found" );
                            return new Vector3 (200, 200, 200); 
                        }
                    }
                }
    }

Это снова отлично работает в редакторе. Это код, который я запускаю на своем устройстве (без сферы проверки)

public void spawnAllTiers(int maxNum)
    {

        if(GameController.trackingReady && !hasTriedSpawn)
        {
            hasTriedSpawn = true;

            int numTimesTried = 0;
            BoxCollider bounds = GetGrid ();
            if (bounds != null) {

                while (tiersSpawned.Length < maxNum && numTimesTried < 70) { //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.bounds);

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

                    numTimesTried++;
                    platformsSpawned = GameObject.FindObjectsOfType<Platform> ();
                    tiersSpawned = GameObject.FindObjectsOfType<Tier> ();
                }

                if(tiersSpawned.Length < maxNum)
                {
                    print ("DIDNT REACH - maxed at "+tiersSpawned.Length);
                }

            }
        }

        //maybe check for num times trying, or if size of all spawned tiers is greater than area approx
    }

    //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));
//      Vector3 pos = currentTier.transform.position; //LATER UNCOMMENT - would be the current tier spawning from


        //TO TEST comment to this line ---------------------------------------------------------------------------
        #if UNITY_EDITOR 

        Instantiate (t, position, Quaternion.identity);
        anchorManager.AddAnchor(t.gameObject);

        #else 

        //------------------------------------------------------------------------------------------
        Instantiate (t, position, Quaternion.identity);
        anchorManager.AddAnchor(t.gameObject);

        #endif
    }

Это не приводит к сбою устройства, но создает ВСЕ в одном и том же месте. Я не могу понять, почему. Если я сделаю это, ПРОВЕРКА на перекрытие:

public void spawnAllTiers(int maxNum)
    {

        if(GameController.trackingReady && !hasTriedSpawn)
        {
            hasTriedSpawn = true;

            int numTimesTried = 0;
            BoxCollider bounds = GetGrid ();
            if (bounds != null) {

                while (tiersSpawned.Length < maxNum && numTimesTried < 70) { //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 (GetGrid ().bounds);

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

                    numTimesTried++;
                    platformsSpawned = GameObject.FindObjectsOfType<Platform> ();
                    tiersSpawned = GameObject.FindObjectsOfType<Tier> ();
                }

                if(tiersSpawned.Length < maxNum)
                {
                    print ("DIDNT REACH - maxed at "+tiersSpawned.Length);
                }

            }
        }

        //maybe check for num times trying, or if size of all spawned tiers is greater than area approx
    }

Снова отлично работает в редакторе, но полностью зависает устройство. Журналы бесполезны, так как я получаю это каждый раз, даже если они не появляются в этих позициях:

SUCCESS - spawn (0.2, -0.9, -0.9)SPHERE: False
SUCCESS - spawn (-0.4, -0.9, 0.2)SPHERE: False
SUCCESS - spawn (0.8, -0.9, 0.2)SPHERE: False
SUCCESS - spawn (-0.4, -0.9, -0.8)SPHERE: False
SUCCESS - spawn (0.9, -0.9, -0.8)SPHERE: False

Что, черт возьми, происходит - почему он зависает только на таком устройстве?


person skyguy    schedule 16.04.2018    source источник
comment
примечание добавьте несколько очень простых операторов Debug.Log .., чтобы узнать, что происходит. Часто что-то зацикливается гораздо больше, чем вы думаете. добавляйте все больше и больше операторов Debug.Log, пока не увидите проблему!   -  person Fattie    schedule 16.04.2018


Ответы (1)


Резюме:

похоже, вам нужен короткий промежуток между каждым появлением.

(Кстати, полезный трюк: научитесь ждать следующего кадра — ознакомьтесь со многими статьями об этом.)


Классический ответ на этот вопрос

https://stackoverflow.com/a/35228592/294884

  • попасть в "фрагменты" для случайных алгоритмов

  • обратите внимание на удобную строку кода в разделе «Как получить наборы уникальных случайных чисел».

Наслаждаться


Не связанная проблема -

Может быть, вам нужно в основном подождать небольшой момент между созданием каждого куба?

Пока в единстве это очень просто Invoke — ваш шаблон кода будет выглядеть примерно так:

В настоящее время ...

for 1 to 100 .. spawn a cube

Делать паузу между каждым...

В Пуск...

Call Invoke("_spawn", 1f)

а потом

func _spawn() {
   if count > 70 .. break
   spawn a cube
   Invoke("_spawn", 1f)
}

Аналогичный пример кода - https://stackoverflow.com/a/36736807/294884
Еще проще - https://stackoverflow.com/a/35807346/294884

Наслаждаться

person Fattie    schedule 16.04.2018
comment
Хорошо.. спасибо. Дело в том, что перед внедрением я думаю, что iPhone все равно будет отказываться из-за какой-то проблемы с памятью ... есть ли способ заставить существующий код работать, если я создаю только максимум 20 кубов? также все кубики одинакового размера - person skyguy; 16.04.2018
comment
действительно, потребовалось время ожидания. Моя единственная проблема сейчас в том, что контрольная сфера на самом деле не работает - все они появляются друг над другом. Это известная проблема с ARKit в реальном мире/iphone в целом? - person skyguy; 18.04.2018
comment
рад, что мы решили проблему @skyguy. Что касается всего в одном и том же месте - проблема AR, на самом деле вам придется задать новый вопрос по этому поводу. - person Fattie; 18.04.2018