2016-09-18 132 views
0

早上好開發人員我知道這個問題以前曾被問過,但我沒有找到解決方案來解決我的問題這些答案,首先我想告訴你,我只是一個團結初學者:嗯,這裏是我的問題:我正在構建一個磚頭破碎機遊戲,我想要做的是改變精靈當它被用球砸磚頭,這樣做,我使用這個腳本:「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

這是因爲你的時間命中從0開始,那麼當你加載一個精靈時,你會扣除1給你-1。在接下來的LoadSprite行中,您嘗試訪問索引爲-1的hitSprites數組(hitSprites [-1]),這當然超出了範圍。

至少,我會添加一些驗證來檢查您的索引的邊界。

0

我不能說出你在做什麼,但是你正在得到那個錯誤,因爲你正在訪問長度> = 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]; 
} 
0

您需要夾緊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>(); 
} 
0

@Programmer @丹 - 庫克@ user2867426 拳頭,我要感謝大家對你的答案,我學到了很多,從你們的話,非常感謝你! 好吧,我有點錯誤解決了我的錯誤哈​​哈。 當我優化我的代碼我注意到,我在確定使用此條件的更新(),而我可以直接用它來OnCollisionEnter2D():

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

,並在某種程度上是固定我的問題,我不知道如何, 也許問題是,它被稱爲每一幀,現在不是! 如果你們可以向我解釋,如果update()的條件解決了問題,我真的很感激它^^ 再次感謝所有人。

+0

lol接受答案然後取消接受....要回答你的問題,那是因爲從'OnCollisionEnter2D'調用它只會在實際存在命中時調用它。但是當你將代碼移動到'Update'函數時,無論是否存在命中,每秒或每幀都會被調用60次。快樂的編碼! – Programmer

+0

@Programmer aaah好吧我現在明白了,所以發生的事情是,在任何命中之前,timesHit = 0;並且因爲spriteIndex = timesHit - 1;然後spriteIndex得到-1,這就是導致問題的原因! 所以解決它的另一種方法是在LoadSprite()方法 的頂部添加「if(timeshit <1)return;」,這將防止spriteIndex獲得值-1:D –

+0

是的,這是正確的。您還應該確保長度不超過或等於'hitSprites'的長度。 'hitSprites.Length - 1'。我在我的回答中解釋了這一點。 – Programmer