我正在制作一款砖块游戏的克隆版本,所以我尝试着在游戏中添加一个乘法球功能。这个视频展示了这个功能。
下面是我的代码://access to all active balls
Ball[] balls = FindObjectsOfType<Ball>();
//loop for the length of the balls
for (int i = 0; i <= balls.Length; i++)
{
if (balls.Length >= 1000)
{
return;
}
else
{
// here I'm trying to fix the issue by checking if the ball exists, so I will call the function if not. return. but console show me same message
if (balls[i] != null)
{
balls[i].CallM3x();
i++;
}
}
}
unity控制台消息为:
IndexOutOfRangeException: Index was outside the bounds of the array.
我上面的代码工作得很好,但问题是有些球在for循环结束前不到一秒就销毁了。
知道如何避免这种情况吗?
你的循环有两个基本问题:
-
你正在循环到
i <= balls.Length
,这将总是抛出错误(在长度为10的数组中没有a[10]
)。 -
你在循环中再次增加
i
,这将跳过项目
将循环条件更改为i < balls.Length
,并移除循环内的i++
同样,您不需要每次都在循环中检查if (balls.Length >= 1000)
—您可以在循环之前检查它(但是超过10,000项的集合有什么问题呢?)
问题是有些球在for循环结束前不到一秒就销毁了
我看不出这有什么问题。你正在创建一个引用数组,你正在循环。即使道具在游戏中被销毁,对象引用仍然存在于你的数组中。可能会有一些其他标志告诉你对象被销毁了(我不是Unity专家),但它们不会在数组中更改为null
。
避免在循环中删除的对象重新引用问题的一个简单方法是将i
从balls.Length
计数到0
,而不是从0
计数到balls.Length
。
for (int i = balls.Length - 1; i >= 0; i--)
同样,你可能想再看看你的for循环:你向上到<= balls.Length
,允许最高索引是= balls.Length
。这个指标出界了,因为我们从0开始计数。我建议在这里使用<
而不是<=
。
Ball[] balls = FindObjectsOfType<Ball>();
for (int i = 0; i < balls.Length; i++)
{
if (balls.Length >= 1000)
{
return;
}
else
{
if (balls[i] != null)
{
balls[i].CallM3x();
// i++; <- This is your problem. Remove it.
}
}
}