2017-02-14 16 views
-3

私はヘビのようなゲームを作成しています。以下のコードでは、ヘビのボディの各セグメントがCharacterクラスのインスタンスです。私は新しい文字を追加しようとすると、私はエラーを取得:オンラインUnity C#ArgumentOutOfRangeException:引数が範囲外です。パラメータ名:index

ArgumentOutOfRangeException: Argument is out of range. Parameter name: index 

その他のリソースは、私が参照しようとしていることを空かリストがあることを提案しました。しかし私は自分のコードでその事実の証拠は見られません。

おそらく自分よりスマートな人が私が間違ったことを見つけることができますか?

using System.Collections; 
using System.Collections.Generic; 
using UnityEngine; 

/* 
* This class controls the entire snake. The snake has a list 
* of segments that are each a character. We can move along the snake 
* by moving the characters bottom up, so that the character replaces 
* the position of the character before him. 
*/ 

public class PlayerController : MonoBehaviour { 

//how many units will he move per 'frame' 
public float moveUnits = 1; 
//how often he will move (every quarter second) 
public float moveTimer = 0.25f; 
private float timeSinceLastMoved; 
public KeyCode dir = KeyCode.RightArrow; 
//locations of boundaries 
public float topBoundary = 4.5f; 
public float bottomBoundary = -4.5f; 
public float leftBoundary = -8.5f; 
public float rightBoundary = 8.5f; 
//Holds all characters for the snake body 
public List<Character> chars = new List<Character>(); 

// Use this for initialization 
void Start() { 
    timeSinceLastMoved = Time.time; 
    getFirstCharacter(); 

} 

// Update is called once per frame 
void Update() { 
    getInput(); 

    if (timeSinceLastMoved + moveTimer < Time.time) { 
     move(); 
     timeSinceLastMoved = Time.time; 
    } 

} 

void getInput() { 

    //if i press right go right, but i can't be going left when i want to go right 
    if (Input.GetKeyDown (KeyCode.RightArrow) && dir != KeyCode.LeftArrow) { 
     dir = KeyCode.RightArrow; 
    } else if (Input.GetKeyDown (KeyCode.LeftArrow) && dir != KeyCode.RightArrow) { 
     dir = KeyCode.LeftArrow; 
    } else if (Input.GetKeyDown (KeyCode.UpArrow) && dir != KeyCode.DownArrow) { 
     dir = KeyCode.UpArrow; 
    } else if (Input.GetKeyDown (KeyCode.DownArrow) && dir != KeyCode.UpArrow) { 
     dir = KeyCode.DownArrow; 
    } 

    //for testing character addition 
    else if (Input.GetKey (KeyCode.A)) { 
     addCharacter(); 
    } 


} 

void move() { 

    float x = 0; 
    float y = 0; 

    if (chars.Count != 0) { 

     //moves the transform in the appropriate directions 
     switch (dir) { 
     case KeyCode.RightArrow: 
      x = transform.position.x + moveUnits; 
      y = transform.position.y; 
      break; 
     case KeyCode.LeftArrow: 
      x = transform.position.x - moveUnits; 
      y = transform.position.y; 
      break; 
     case KeyCode.UpArrow: 
      x = transform.position.x; 
      y = transform.position.y + moveUnits; 
      break; 
     case KeyCode.DownArrow: 
      x = transform.position.x; 
      y = transform.position.y - moveUnits; 
      break; 
     default: 
      break; 
     } 
     //prevents him from moving outside the set boundaries 
     x = Mathf.Clamp (x, leftBoundary, rightBoundary); 
     y = Mathf.Clamp (y, bottomBoundary, topBoundary); 
     Vector2 pos = new Vector2 (x, y); 
     //this moves the whole snake 
     transform.position = pos; 
     //this moves the first snake segment 
     chars[0].transform.position = pos; 

     //for all characters(aka snake segments) 
     //take the position of the segment before you 
     for (int i = chars.Count - 1; i > 0; i++) { 
      chars [i].transform.position = chars [i - 1].transform.position; 
     } 
    } 

} 

void addCharacter() { 
    //the position of the last segment 
    Vector2 prevCharPos = chars[chars.Count-1].transform.position; 
    Vector2 pos; 
    float x = 0; 
    float y = 0; 
    switch (dir) { 
    case KeyCode.RightArrow: 
     x = prevCharPos.x - moveUnits; 
     y = prevCharPos.y; 
     break; 
    case KeyCode.LeftArrow: 
     x = prevCharPos.x + moveUnits; 
     y = prevCharPos.y;; 
     break; 
    case KeyCode.UpArrow: 
     x = prevCharPos.x; 
     y = prevCharPos.y + moveUnits; 
     break; 
    case KeyCode.DownArrow: 
     x = prevCharPos.x; 
     y = prevCharPos.y - moveUnits; 
     break; 
    default: 
     break; 
    } 
    pos = new Vector2 (x, y); 
    //make a new character at the position behind the last segment 
    Character newChar = Instantiate (chars[chars.Count - 1], pos, Quaternion.identity, this.transform); 
    //add him to the list 
    chars.Add (newChar); 
} 

void getFirstCharacter() { 
    //find the character that already exists and add him to the list 
    GameObject firstChar = GameObject.Find ("Character"); 
    if (firstChar != null) { 
     chars.Add(firstChar.GetComponent<Character>()); 
    } 
} 

}

+2

希望を解決するを理解するのに役立ちますことを願っています。なぜこれが不要なコード行なのでしょうか? –

+0

あなたはその例外をどのような行にしますか?その点までデバッグすることで、問題の原因を理解するのに役立ちます! – Adil

+0

エラーが発生した行を教えてください。 – mindOfAi

答えて

4
は、ループ条件のためにあなたを変更し

場合だけ内側のループのためにあなたを置きます。理論的には、範囲外の例外が発生します。

あなたがアクセスしようとしたときに例外が発生します意味し、

The exception that is thrown when the value of an argument is outside the allowable range of values as defined by the invoked method

:私はあなたの意図は、MSDNのドキュメントArgumentOutOfRangeExceptionによる

for (int i = chars.Count - 1; i > 0; i--)

0

チェック

  if(chars.Count>0){ 
      //for all characters(aka snake segments) 
        //take the position of the segment before you 
        for (int i = chars.Count - 1; i > 0; i++) { 
         chars [i].transform.position = chars [i - 1].transform.position; 
        } 
      } 
      else{ 
       Debug.Log("Warning:: chars Count is less than 1"); 
} 
0

あるべきことであると考えてい

for (int i = chars.Count - 1; i > 0; i++) chars [i].transform.position = chars [i - 1].transform.position;

そのインデックス値に基づいてコレクションからのアイテムですが、実際にはそのインデックスは「いいえ」ですインデックスの範囲内のt。ケースコレクションのほとんどは0のインデックスに基づいているため、特定の値が0未満の場合、またはコレクション内の要素数より大きい場合はアクセス中にこの例外が発生します。

chars [i - 1]を別の場所で使用していることがわかります。iの値が0の場合、例外が発生します。

私たちは、あなたが i-1を使用して前の項目にアクセスしても、ループ制限が未満でなければならない場合、 charsはコレクションとすると、あなたがインデックスに基づいてアイテムにアクセスしている、 chars.Count > 0を確認することが重要であると言うことができ要するに

chars.Count

これは一般的な答えであるが、それは、このエラーの原因とどのように彼らにそれはあなたの最初のポストではなく、あなたが質問をする方法を知っていること

関連する問題