Unity - 实例化对象在 Coroutine 中的相同位置生成,而直接实例化它们会正确生成
Unity - Instantiated objects spawn on the same position in Coroutine, while instantiate them directly do spawn correctly
我想达到的目标:
我正在创建一个程序生成的城市。我让道路正常工作,连同房屋的生成,它们沿着道路生成,如果它们与道路 and/or 另一座建筑物相撞,则不会生成。现在因为我有时想加载一个大城市,这会花费很多计算时间,所以我想放入一个协程来慢慢加载所有房屋。 (请告诉我是否有更好的方法,或者“正确”的方法,这是我所知道的唯一可行的方法)。
我做了什么/问题:
所以我所做的是,我用来创建房屋的所有部分都放在一个列表中,一旦所有房屋都预生成(还不是 spawned/instantiated),我想使用协程生成他们单独。但是每当我使用协程生成它们时,它们就会在彼此内部生成。
虽然如果我直接从他们的脚本(仍然使用列表)生成它们,它们确实会正确生成,但我不知道我做错了什么以及如何解决这个问题。
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,它将生成道路,这些道路点存储在列表中。生成道路后,道路生成器将调用建筑物生成器。建筑物生成器将遍历所有道路的整个列表,并在它们旁边创建建筑物,这些建筑物是通过第三个脚本(未实例化)创建的。构建脚本,该脚本包含构建部分,并将它们拼凑在一起并检查冲突(第一个代码块)。一旦这些建筑物全部创建并放入列表中,buildingGenerator 将启动协程并实例化所有这些建筑物(因此在错误的位置)(第二个代码块)。
希望我提供了足够的信息,否则我很乐意提供更多信息。
好的,我终于让它工作了。问题不在协程,而在列表。我的代码会不断覆盖我的列表对象。所以我创建了一个新脚本,具有对象、位置和旋转等基本属性。然后我将这些新脚本添加到列表中,并在协程中生成它们。 (在我的评论中,我说我在修复此问题后遇到了一些其他问题,这是因为我使用了 .bounds.max.y,而我应该使用 .bounds.size.y。因此这也是该问题的修复方法)。
我希望以后有人会觉得这有用!
我想达到的目标:
我正在创建一个程序生成的城市。我让道路正常工作,连同房屋的生成,它们沿着道路生成,如果它们与道路 and/or 另一座建筑物相撞,则不会生成。现在因为我有时想加载一个大城市,这会花费很多计算时间,所以我想放入一个协程来慢慢加载所有房屋。 (请告诉我是否有更好的方法,或者“正确”的方法,这是我所知道的唯一可行的方法)。
我做了什么/问题:
所以我所做的是,我用来创建房屋的所有部分都放在一个列表中,一旦所有房屋都预生成(还不是 spawned/instantiated),我想使用协程生成他们单独。但是每当我使用协程生成它们时,它们就会在彼此内部生成。 虽然如果我直接从他们的脚本(仍然使用列表)生成它们,它们确实会正确生成,但我不知道我做错了什么以及如何解决这个问题。
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,它将生成道路,这些道路点存储在列表中。生成道路后,道路生成器将调用建筑物生成器。建筑物生成器将遍历所有道路的整个列表,并在它们旁边创建建筑物,这些建筑物是通过第三个脚本(未实例化)创建的。构建脚本,该脚本包含构建部分,并将它们拼凑在一起并检查冲突(第一个代码块)。一旦这些建筑物全部创建并放入列表中,buildingGenerator 将启动协程并实例化所有这些建筑物(因此在错误的位置)(第二个代码块)。
希望我提供了足够的信息,否则我很乐意提供更多信息。
好的,我终于让它工作了。问题不在协程,而在列表。我的代码会不断覆盖我的列表对象。所以我创建了一个新脚本,具有对象、位置和旋转等基本属性。然后我将这些新脚本添加到列表中,并在协程中生成它们。 (在我的评论中,我说我在修复此问题后遇到了一些其他问题,这是因为我使用了 .bounds.max.y,而我应该使用 .bounds.size.y。因此这也是该问题的修复方法)。
我希望以后有人会觉得这有用!