Unity - 从网格中的数组生成对象导致重复?
Unity - Spawning Objects from Array in a grid causing duplicates?
我正在尝试将所有可用的预制件生成到网格中以便于查看它们。基本上作为一种工具来挑选各种建筑部件来制作定制建筑(如果该信息有帮助,特别是使用 SyntyStudios 包)
我可以获取我想要的所有资源并制作一个数组,这不是问题所在。当我尝试遍历数组中的每个对象并将它们生成到它们的“网格位置”时,我的代码在移动到下一个对象之前在每个位置生成相同的对象。
这是我的代码:
for(int a = 0; a < allPrefabs.Count; a++)
SpawnAssets(allPrefabs[a]);
这构建了我的数组,据我所知,它再次工作得很好(它确实填充在检查器中)
void SpawnAssets(GameObject obj)
{
spawnPos = Vector3.zero;
Debug.Log("Spawn Mechanic v5");
int width = allPrefabs.Count/2;
int depth = allPrefabs.Count/2;
for(int z = 0; z < depth; z++)
for(int x = 0; x < width; x++){
GameObject assetClone = Instantiate(obj,Vector3.zero,Quaternion.identity);
Vector3 spawnPos = new Vector3(x*offsetDistance,0,z*offsetDistance);
assetClone.transform.position = spawnPos;
assetClone.transform.parent = parentObj;
}
}
我认为该代码是问题所在。我可以将 Instantiate 移出 'for' 循环并删除重复,但它只是遍历位置,然后我的所有资产都在最后一个位置彼此重叠。
我查看了文档,遵循了一些 YouTube 教程,但似乎没有任何方法可以解决这个问题,而且我显然对错误视而不见,因为看起来我正在做与他们完全相同的事情(文档和 YT) 是。
我希望有另一双眼睛来帮助我指出这无疑是我的一个非常愚蠢的疏忽。非常感谢您的宝贵时间!
https://imgur.com/A7A2vlP
编辑
这是我得到的重复问题的图像。每个项目生成 39 次(构建数组时有 39 个预制件可用,因此它实例化相同预制件的次数与它们的数组一样长,如果这有意义的话)
我看到的主要问题是,您实际上是在嵌套循环中实例化您的对象。那肯定会导致多个对象。
这样想。每次要实例化一个对象时,都要遍历整个网格,并在每个网格位置上放置一个对象。然后,您转到下一个对象并执行相同的操作。
也许您忘记了一个 if 语句来检查您是否应该实际实例化。
或者,您可以尝试在外部变量(可能是 vector3)上设置最后实例化的位置,并使用它来确定新的位置。
理解您所期望的确切行为有点困难。
目前,所有预制件都在所有位置也就不足为奇了,因为这正是您告诉它要做的。
- 您遍历所有现有的预制件
- 您使用当前的预制件并将其生成到
SpawnAssets
中网格中的每个位置
如果我理解你更正你想要的是生成一个(尽可能正方形)网格,其中每个预制件都精确地生成一次一次。
private void Start()
{
SpawnAssets(allPrefabs);
}
void SpawnAssets(List<GameObject> obj)
{
// You do NOT want to divide the amount of prefabs by 2
// A grid has dimensions x * y ... not x + y!
// You want the square root of the amount of all prefabs
// but rounded up to the next full number
var width = Mathf.CeilToInt(Mathf.Sqrt(allPrefabs.Count));
// Then you want the second dimension so simply divide the entire amount by the
// previously calculated width, then again round up to the next full number
var depth = Mathf.CeilToInt(allPrefabs.Count / (float) width);
// have only ONE counter for the created objects
for (var i = 0; i < allPrefabs.Count; i++)
{
// Calculate x and z indices from the one given index
// depends a bit on how you want to lay out the prefabs
// you can easily exchange whether you want to dive/modulo by "depth" or "width"
// you can also exchange whether you want to use division/modulo for "z" or "x"
var z = i / depth;
var x = i % depth;
var spawnPos = new Vector3(x * offsetDistance, 0, z * offsetDistance);
var assetClone = Instantiate(obj[i], spawnPos, Quaternion.identity, parentObj);
}
}
我正在尝试将所有可用的预制件生成到网格中以便于查看它们。基本上作为一种工具来挑选各种建筑部件来制作定制建筑(如果该信息有帮助,特别是使用 SyntyStudios 包)
我可以获取我想要的所有资源并制作一个数组,这不是问题所在。当我尝试遍历数组中的每个对象并将它们生成到它们的“网格位置”时,我的代码在移动到下一个对象之前在每个位置生成相同的对象。
这是我的代码:
for(int a = 0; a < allPrefabs.Count; a++)
SpawnAssets(allPrefabs[a]);
这构建了我的数组,据我所知,它再次工作得很好(它确实填充在检查器中)
void SpawnAssets(GameObject obj)
{
spawnPos = Vector3.zero;
Debug.Log("Spawn Mechanic v5");
int width = allPrefabs.Count/2;
int depth = allPrefabs.Count/2;
for(int z = 0; z < depth; z++)
for(int x = 0; x < width; x++){
GameObject assetClone = Instantiate(obj,Vector3.zero,Quaternion.identity);
Vector3 spawnPos = new Vector3(x*offsetDistance,0,z*offsetDistance);
assetClone.transform.position = spawnPos;
assetClone.transform.parent = parentObj;
}
}
我认为该代码是问题所在。我可以将 Instantiate 移出 'for' 循环并删除重复,但它只是遍历位置,然后我的所有资产都在最后一个位置彼此重叠。
我查看了文档,遵循了一些 YouTube 教程,但似乎没有任何方法可以解决这个问题,而且我显然对错误视而不见,因为看起来我正在做与他们完全相同的事情(文档和 YT) 是。
我希望有另一双眼睛来帮助我指出这无疑是我的一个非常愚蠢的疏忽。非常感谢您的宝贵时间!
https://imgur.com/A7A2vlP 编辑 这是我得到的重复问题的图像。每个项目生成 39 次(构建数组时有 39 个预制件可用,因此它实例化相同预制件的次数与它们的数组一样长,如果这有意义的话)
我看到的主要问题是,您实际上是在嵌套循环中实例化您的对象。那肯定会导致多个对象。
这样想。每次要实例化一个对象时,都要遍历整个网格,并在每个网格位置上放置一个对象。然后,您转到下一个对象并执行相同的操作。
也许您忘记了一个 if 语句来检查您是否应该实际实例化。
或者,您可以尝试在外部变量(可能是 vector3)上设置最后实例化的位置,并使用它来确定新的位置。
理解您所期望的确切行为有点困难。
目前,所有预制件都在所有位置也就不足为奇了,因为这正是您告诉它要做的。
- 您遍历所有现有的预制件
- 您使用当前的预制件并将其生成到
SpawnAssets
中网格中的每个位置
如果我理解你更正你想要的是生成一个(尽可能正方形)网格,其中每个预制件都精确地生成一次一次。
private void Start()
{
SpawnAssets(allPrefabs);
}
void SpawnAssets(List<GameObject> obj)
{
// You do NOT want to divide the amount of prefabs by 2
// A grid has dimensions x * y ... not x + y!
// You want the square root of the amount of all prefabs
// but rounded up to the next full number
var width = Mathf.CeilToInt(Mathf.Sqrt(allPrefabs.Count));
// Then you want the second dimension so simply divide the entire amount by the
// previously calculated width, then again round up to the next full number
var depth = Mathf.CeilToInt(allPrefabs.Count / (float) width);
// have only ONE counter for the created objects
for (var i = 0; i < allPrefabs.Count; i++)
{
// Calculate x and z indices from the one given index
// depends a bit on how you want to lay out the prefabs
// you can easily exchange whether you want to dive/modulo by "depth" or "width"
// you can also exchange whether you want to use division/modulo for "z" or "x"
var z = i / depth;
var x = i % depth;
var spawnPos = new Vector3(x * offsetDistance, 0, z * offsetDistance);
var assetClone = Instantiate(obj[i], spawnPos, Quaternion.identity, parentObj);
}
}