Ce que je veux réaliser :
Je crée une ville générée de manière procédurale. J'ai réussi à faire fonctionner les routes, ainsi que la création des maisons, elles apparaissent le long de la route et ne sont pas créées si elles entrent en collision avec la route et/ou un autre bâtiment. Maintenant, comme je veux parfois charger une grande ville, cela coûte beaucoup de temps de calcul, alors je voulais mettre une Coroutine pour charger lentement toutes les maisons. (S'il vous plaît dites-moi s'il y a une meilleure façon, ou une façon "correcte", c'est la seule chose que je savais qui pourrait fonctionner).
Ce que j'ai fait / Problème :
Donc ce que j'ai fait, c'est que tous les segments que j'utilise pour créer une maison, je les mets dans une liste, et une fois que toutes les maisons sont pré-générées (pas encore spawned/instantiated) je veux utiliser la coroutine pour les spawn individuellement. Mais lorsque j'utilise la coroutine pour les faire apparaître, elles apparaissent les unes dans les autres. Alors que si je les fais naître directement à partir de leur script (en utilisant toujours la liste), ils naissent correctement, je n'ai aucune idée de ce que je fais mal et de la façon de résoudre ce problème.
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();
}
}
Informations supplémentaires :
Je fais usage de 3 scripts pour spawn la ville entière, le roadGenerator, qui va spawn les routes, ces points de route sont stockés dans une liste. Une fois les routes générées, le roadgenerator appelle le building Generator. Le générateur de bâtiment va parcourir toute la liste de toutes les routes, et créer des bâtiments à côté d'elles, les bâtiments sont créés via un 3ème scripts (non instancié). Le scripts de construction, ce scripts contient les segments de construction, et va les assembler et aussi vérifier les collisions (Premier bloc de code). Une fois que ces bâtiments sont tous créés et mis dans une liste, le buildingGenerator va lancer la coroutine et instancier tous ces bâtiments (donc sur la mauvaise position)(Second bloc de code).
J'espère avoir fourni suffisamment d'informations, sinon je serais heureux d'en fournir davantage.