“Unity3D”索引超出范围例外:数组索引超出范围(尝试更改精灵命中时)
早上好开发人员我知道这个问题以前曾被问过,但我没有找到解决方案来解决我的问题这些答案,首先我想告诉你,我只是一个团结初学者:嗯,这里是我的问题:我正在构建一个砖头破碎机游戏,我想要做的是改变精灵当它被用球砸砖头,这样做,我使用这个脚本:“Unity3D”索引超出范围例外:数组索引超出范围(尝试更改精灵命中时)
public int maxHits;
public int timesHit;
private LevelManager levelManager;
public Sprite[] hitSprites;
void Start() {
timesHit = 0;
levelManager = GameObject.FindObjectOfType<LevelManager>();
}
void OnCollisionEnter2D(Collision2D collision) {
print ("collison");
timesHit++;
}
// Update is called once per frame
void Update() {
if (timesHit >= maxHits) {
Destroy (gameObject);
} else {
LoadSprite();
}
}
void LoadSprite(){
int spriteIndex = timesHit - 1;
this.GetComponent<SpriteRenderer>().sprite = hitSprites [spriteIndex];
}
}
,但我得到这个错误:IndexOutOfRangeException: Array index is out of range. Brick.LoadSprite() (at Assets/Scripts/Brick.cs:34)
,我得到它的每一帧!小号o它太慢了游戏场景,我无法再测试我的游戏了。你能告诉我我做错了什么以及如何解决它吗?如果你指导我学习更多关于我的错误的课程并且不会再次这样做,这可能会有所帮助。
这是因为你的时间命中从0开始,那么当你加载一个精灵时,你会扣除1给你-1。在接下来的LoadSprite行中,您尝试访问索引为-1的hitSprites数组(hitSprites [-1]),这当然超出了范围。
至少,我会添加一些验证来检查您的索引的边界。
我不能说出你在做什么,但是你正在得到那个错误,因为你正在访问长度> = hitSprites
的索引。
在使用前,您应该检查spriteIndex
变量是否小于hitSprites
的长度。
您的新LoadSprite
功能应该是:
void LoadSprite()
{
int spriteIndex = 0;
//Don't decrement if timesHit is 0
if (timesHit > 0)
{
spriteIndex = timesHit - 1;
}
else
{
spriteIndex = timesHit;
}
//Return/Exit function if spriteIndex is equals or more than hitSprites length
if (spriteIndex > hitSprites.Length - 1)
{
return;
}
this.GetComponent<SpriteRenderer>().sprite = hitSprites[spriteIndex];
}
您需要夹紧spriteIndex不去小于0(第一个数组索引)和超过hitSprites.Length 1(最后一个数组索引)减少。
void LoadSprite(){
int spriteIndex = Mathf.Clamp(timesHit - 1, 0, hitSprites.Length - 1);
this.GetComponent<SpriteRenderer>().sprite = hitSprites [spriteIndex];
}
}
提示: 不要叫太多GetComponent在更新..预取所有组件在清醒以后使用。
private SpriteRenderer _spriteRenderer;
void Awake()
{
_spriteRenderer = GetComponent<SpriteRenderer>();
}
@Programmer @丹 - 库克@ user2867426 拳头,我要感谢大家对你的答案,我学到了很多,从你们的话,非常感谢你! 好吧,我有点错误解决了我的错误哈哈。 当我优化我的代码我注意到,我在确定使用此条件的更新(),而我可以直接用它来OnCollisionEnter2D():
if (timesHit >= maxHits) {
Destroy (gameObject);
} else {
LoadSprite();
}
,并在某种程度上是固定我的问题,我不知道如何, 也许问题是,它被称为每一帧,现在不是! 如果你们可以向我解释,如果update()的条件解决了问题,我真的很感激它^^ 再次感谢所有人。
lol接受答案然后取消接受....要回答你的问题,那是因为从'OnCollisionEnter2D'调用它只会在实际存在命中时调用它。但是当你将代码移动到'Update'函数时,无论是否存在命中,每秒或每帧都会被调用60次。快乐的编码! – Programmer
@Programmer aaah好吧我现在明白了,所以发生的事情是,在任何命中之前,timesHit = 0;并且因为spriteIndex = timesHit - 1;然后spriteIndex得到-1,这就是导致问题的原因! 所以解决它的另一种方法是在LoadSprite()方法 的顶部添加“if(timeshit
是的,这是正确的。您还应该确保长度不超过或等于'hitSprites'的长度。 'hitSprites.Length - 1'。我在我的回答中解释了这一点。 – Programmer