簡體   English   中英

“ Unity3D”索引超出范圍異常:數組索引超出范圍(在命中時嘗試更改精靈)

[英]“Unity3D” Index Out Of Range Exception: Array index is out of range (trying to change sprite when hit)

早上好,開發人員我知道這個問題以前曾有人問過,但是我在那些答案中沒有找到解決問題的方法,首先我想告訴你我只是unity:p的初學者。我的問題:我正在構建一個破磚游戲,我要嘗試的是在被球擊中時改變磚的精靈,為此,我正在使用以下腳本:

 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) IndexOutOfRangeException: Array index is out of range. Brick.LoadSprite () (at Assets/Scripts/Brick.cs:34)

而且每一幀都在獲取它!因此它極大地減緩了游戲場景,並且我無法再測試游戲了。 您能告訴我我做錯了什么以及如何解決嗎?如果您將我引導到學習更多關於我的錯誤的知識而不回頭再做可能會有所幫助。

發生這種情況是因為您的命中時間從0開始,然后在加載精靈時,您減去1得-1。 然后,在LoadSprite的以下行中,您嘗試訪問索引-1(hitSprites [-1])上的hitSprites數組,該數組當然超出范圍。

至少,我會添加一些驗證來檢查索引的范圍。

我無法告訴您正在做什么,但是由於您正在訪問> = 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];
     }
 }

提示:不要在Update中調用太多的GetComponent。要預喚醒所有組件,以備后用。

private SpriteRenderer _spriteRenderer;

void Awake()
{
_spriteRenderer = GetComponent<SpriteRenderer> ();
}

@程序員@ Dan-Cook @ user2867426拳頭,我要感謝大家的回答,我從你們這里學到了很多東西,非常感謝!! 好吧,我有點是錯誤地修復了我的錯誤。 當我優化代碼時,我注意到我在update()中使用if條件,而我可以直接將其用於OnCollisionEnter2D():

if (timesHit >= maxHits) {
     Destroy (gameObject);
 } else {
     LoadSprite ();
 }

並以某種方式解決了我的問題,我不知道如何解決,也許問題是它被稱為每一幀,但現在不是! 如果你們可以向我解釋,如果條件來自update()可以解決該問題,我將非常感激^^再次感謝大家。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM