Объекты, созданные в единстве, появляются в одной и той же позиции в сопрограмме, в то время как их создание напрямую выполняется правильно

#c# #unity3d #instantiation #coroutine

#c# #unity3d #создание экземпляра #сопрограмма

Вопрос:

Чего я хочу достичь:

Я создаю процедурно сгенерированный город. У меня работают дороги, вместе с появлением домов они появляются вдоль дороги и не появляются, если они сталкиваются с дорогой и / или другим зданием. Теперь, поскольку я иногда хочу загрузить большой город, это требует много вычислительного времени, поэтому я хотел ввести сопрограмму для медленной загрузки во всех домах. (Пожалуйста, скажите мне, есть ли лучший способ или «правильный» способ, это единственное, что я знал, что может работать).

Что я сделал / Проблема:

Итак, что я сделал, все сегменты, которые я использую для создания дома, я помещаю в список, и как только все дома предварительно созданы (еще не созданы / не созданы), я хочу использовать сопрограмму для их создания по отдельности. Но всякий раз, когда я использую сопрограмму для их создания, они появляются внутри друг друга. Хотя, если я создаю их непосредственно из их скрипта (все еще используя список), они появляются правильно, я понятия не имею, что я делаю неправильно и как это исправить.

 public void Spawner(Vector3 buildingPosition, Quaternion buildingRotation, int buildingHeight, GameObject buildingParent, LayerMask m_LayerMask, BuildingGenerator buildGenerator)
    {
        GameObject baseBuilding = buildingBase[Random.Range(0, buildingBase.Count)];
        baseBuilding.transform.position = buildingPosition;
        baseBuilding.transform.rotation = buildingRotation;

        Debug.Log(baseBuilding.transform.position);

        Collider[] hitColliders = Physics.OverlapBox(baseBuilding.transform.position, baseBuilding.GetComponentInChildren<Renderer>().bounds.extents /2, Quaternion.identity, m_LayerMask);
        if (hitColliders.Count() > 1)
        {
            return;
        }
        buildGenerator.Segments.Add(baseBuilding);
        buildingPosition.y  = baseBuilding.GetComponentInChildren<Renderer>().bounds.max.y - buildingPosition.y;

        for (int i = 0; i <= buildingHeight; i  )
        {
            buildingRotation *= Quaternion.Euler(0, 0, 0);
            GameObject middleBuilding = buildingMiddle[Random.Range(0, buildingMiddle.Count)];
            middleBuilding.transform.position = buildingPosition;
            middleBuilding.transform.rotation = buildingRotation;
            //buildGenerator.Segments.Add(middleBuilding);

            buildingPosition.y  = middleBuilding.GetComponentInChildren<Renderer>().bounds.max.y - buildingPosition.y;

        }
        if (buildingRoof.Count != 0)
        {
            GameObject roofBuilding = buildingRoof[Random.Range(0, buildingRoof.Count)];
            roofBuilding.transform.position = buildingPosition;
            roofBuilding.transform.rotation = buildingRotation;
            buildGenerator.Segments.Add(roofBuilding);
        }
        Instantiate(buildGenerator.Segments[1]);                //If i use this, they spawn on the correct place.
        Debug.Log(buildGenerator.Segments.Count);

    }
  
     {
        StartCoroutine(LoadSegments(buildingParent));
    }
    public IEnumerator LoadSegments(GameObject buildingParent)
    {
        for (int i = 0; i < Segments.Count; i  )
        {
            GameObject SpawnedSegment = Instantiate(Segments[i]);
            //SpawnedSegment.transform.parent = buildingParent.transform;
            yield return new WaitForEndOfFrame();
        }
    }
  

Дополнительная информация:

Я использую 3 скрипта для создания целого города, roadGenerator, который будет создавать дороги, эти дорожные точки сохраняются в списке. После создания дорог roadgenerator вызовет генератор зданий. Генератор зданий просматривает весь список всех дорог и создает здания помимо них, здания создаются с помощью 3-го скрипта (не создается экземпляр). Сценарий построения, этот сценарий содержит сегменты построения, и соберет их вместе, а также проверит наличие коллизий (первый блок кода). Как только все эти здания будут созданы и помещены в список, buildingGenerator запустит сопрограмму и создаст экземпляры всех этих зданий (таким образом, в неправильной позиции) (второй блок кода).

Надеюсь, я предоставил достаточно информации, иначе я был бы рад предоставить больше.

Комментарии:

1. Можете ли вы указать версию, отличную от сопрограммы, которая работает? Потому что теоретически между этими двумя нет разницы, и я предполагаю, что вы делаете что-то другое «обычным» способом.

2. Я уже добавил рабочий, я поместил за ним комментарий, его в первом скрипте, предпоследняя строка. Я понял, в чем проблема, проблема заключалась в том, что список постоянно переопределялся. Итак, я исправил это, создав новый класс, который содержит объекты, позиции и повороты, но все равно работает не так, как я хочу. После того, как первые 2 объекта появляются правильно, все остальные пропускают один и помещаются друг в друга.

Ответ №1:

Хорошо, итак, я наконец-то заработал. Проблема была не в сопрограмме, а в списке. Мой код постоянно переопределяет объекты моего списка. Итак, я создал новый скрипт с базовыми атрибутами, такими как объект, положение и поворот. Итак, затем я добавляю эти новые сценарии в список и создаю их в сопрограмме. (В своем комментарии я сказал, что у меня были некоторые другие проблемы после того, как я исправил это, это потому, что я использовал .bounds.max.y , в то время как я должен был использовать .bounds.size.y . Таким образом, это также исправление для этого).

Я надеюсь, что кто-то в будущем может найти это полезным!