#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 . Таким образом, это также исправление для этого).
Я надеюсь, что кто-то в будущем может найти это полезным!