ここに最初の投稿配列インデックスが範囲外ですが、定義する必要があります。プログラミング初心者向け
私は自己啓発のC#と団結しており、宝石類に類似した "マッチ3"スタイルのゲームに取り組んでいます。私はチュートリアルに従って以下に掲載されたコードをすべて書きましたが、自分自身とコメントセクションの他の人たちは、配列が範囲外であるという問題を抱えています。
コンパイラが言っているとおりのエラーです。
IndexOutOfRangeException: Array index is out of range.
CreateGame.CheckGrid() (at Assets/Scripts/CreateGame.cs:181)
CreateGame.Update() (at Assets/Scripts/CreateGame.cs:229)
CreateGame.cs(プロジェクト全体の唯一のスクリプト)の完全なコードが下に貼り付けられます。しかし、あなたを助けるために、私はこれを索引で調べたことから、配列に格納されていないものを検索するたびにそれが起こると言います。私のベルトの下にある2つのプロジェクト(チュートリアルからも)を持っているだけで、この問題を実際どのように修正するかについての技術的な知識は不足しています。
配列が0より小さい場合(負の値など)、コンパイラは-1が明らかに範囲外であるため、このエラーを返します。
私は、これらのif文と関係があると思います。具体的には、cの整数から1を引いた部分です。上記の文
for (int c = 0; c < cols; c++)
のために、この内部にネストされているが
if (tiles[c, r] != null && tiles[c - 1, r] != null)
だからCの値がゼロより小さいことはありません、または私は声明のためにこれのロジックを誤解しています、Cの開始を行います0に設定し、cols変数よりも小さければ1を加算するか、またはc = 0でforループを最初に完了しますか?この問題を解決する方法はかなり正確ではありません。
また、配列サイズは、私が作業しているシーンのGameObject(インスペクタ内)で4と定義されています。また、4つの別々のオブジェクトプレハブがタイルの4つの値に割り当てられています配列の位置を(コードのように)タイル配列に格納します。また、csスクリプトは単一のゲームオブジェクトにのみ添付されているため、実行中のコードのインスタンスは複数ありません。
申し訳ありませんが、これはうまく整理されていないか何か、私はわずか1週間学習しています。
ありがとうございます! :)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Tile
{
public GameObject tileObj;
public string type;
public Tile(GameObject obj, string t)
{
tileObj = obj;
type = t;
}
}
public class CreateGame : MonoBehaviour
{
GameObject tile1 = null;
GameObject tile2 = null;
public GameObject[] tile;
List<GameObject> tileBank = new List<GameObject>();
static int rows = 8;
static int cols = 8;
bool renewBoard = false;
Tile[,] tiles = new Tile[cols, rows];
void Start()
{
//List population
int numCopies = (rows * cols)/3;
for (int i = 0; i < numCopies; i++)
{
for(int j = 0; j < tile.Length; j++) // J becomes the int = to number of tile prefabs added
{
GameObject o = (GameObject)Instantiate
(tile [j], new Vector3 (-10, -10, 0), tile [j].transform.rotation); // creates a clone tile of the screen
o.SetActive (false);
tileBank.Add (o); // adds tile (game object called o) to the array (not shuffled)
}
}
ShuffleList(); //Shuffles the list of tile-bank after the list has been populated
//Populates rows and columns with tiles from tileBank array
for (int r = 0; r < rows; r++)
{
for (int c = 0; c < cols; c++)
{
Vector3 tilePos = new Vector3 (c - 2, r - 4, 0); //creates tiles with an offset (-2x and -4y) to place them in scene
for (int n = 0; n < tileBank.Count; n++)
{
GameObject o = tileBank [n];
if (!o.activeSelf) // if the tile is not active move it and make it active
{
o.transform.position = new Vector3 (tilePos.x, tilePos.y, tilePos.z); //moves tile into position, it was stored inactive at -10,-10
o.SetActive (true);
tiles[c, r] = new Tile (o, o.name); //Stores tile back into array
n = tileBank.Count + 1; //Update tile count
}
}
}
}
}
//Shuffles the order of the array storing the tiles
void ShuffleList()
{
System.Random rand = new System.Random();
int r = tileBank.Count;
while (r > 1)
{
r--;
int n = rand.Next (r + 1);
GameObject val = tileBank [n];
tileBank [n] = tileBank [r];
tileBank [r] = val;
}
}
//checks for missing tiles and adds new ones from array, also drops tiles down if there is an opening
void RenewGrid()
{
bool anyMoved = false;
ShuffleList();
for (int r = 1; r < rows; r++)
{
for (int c = 0; c < cols; c++)
{
if (r== rows - 1 && tiles[c, r] == null)
//if in the top row and there are no tiles
{
Vector3 tilePos = new Vector3 (c, r, 0);
for (int n = 0; n < tileBank.Count; n++)
{
GameObject o = tileBank [n];
if (!o.activeSelf)
{
o.transform.position = new Vector3 (tilePos.x, tilePos.y, tilePos.z);
o.SetActive (true);
tiles [c, r] = new Tile (o, o.name);
n = tileBank.Count + 1;
}
}
}
if (tiles[c, r - 1] != null)
{
if (tiles[c, r - 1] == null)
//drop down if space below is empty
{
tiles [c, r - 1] = tiles [c, r];
tiles [c, r - 1].tileObj.transform.position = new Vector3 (c, r - 1, 0);
tiles [c, r] = null;
anyMoved = true;
}
}
}
}
if (anyMoved)
{
Invoke ("RenewGrid", 0.5f);
}
}
void CheckGrid()
{
int counter = 1;
//check in columns for matches
for (int r = 0; r < rows; r++) //repeats function until you have satisfied the number of rows
{
counter = 1;
for (int c = 1; c < cols; c++)
{
if (tiles[c, r] != null && tiles[c - 1, r] != null) //if the tiles exist (not null)
{
if (tiles[c, r].type == tiles [c - 1, r].type) //if there is a match add 1 to the counter for match checks
{
counter++;
}
else
{
counter = 1; //reset counter
}
//if a match is found remove tiles
if (counter == 3)
{
if (tiles [c, r] != null)
{
tiles [c, r].tileObj.SetActive(false);
}
if (tiles [c - 1, r] !=null)
{
tiles [c - 1, r].tileObj.SetActive(false);
}
if (tiles [c - 2, r] !=null)
{
tiles [c - 2, r].tileObj.SetActive(false);
}
tiles[c , r] = null; // changes values to null in the 2D matrix
tiles[c - 1, r] = null;
tiles[c - 2, r] = null;
renewBoard = true;
}
}
}
}
//check in rows for matches
for (int c = 0; c < cols; c++)
{
counter = 1;
for (int r = 1; c < rows; r++)
{
if (tiles[c, r] != null && tiles[c - 1, r] != null) //if the tiles exist (not null)
{
if (tiles[c, r].type == tiles [c - 1, r].type) //if there is a match add 1 to the counter for match checks
{
counter++;
}
else
{
counter = 1; //reset counter
}
//if a match is found remove tiles
if (counter == 3)
{
if (tiles [c, r] != null)
{
tiles [c, r].tileObj.SetActive(false);
}
if (tiles [c, r - 1] !=null)
{
tiles [c, r - 1].tileObj.SetActive(false);
}
if (tiles [c, r - 2] !=null)
{
tiles [c, r - 2].tileObj.SetActive(false);
}
tiles[c, r] = null; // changes values to null in the 2D matrix
tiles[c, r - 1] = null;
tiles[c, r - 2] = null;
renewBoard = true;
}
}
}
}
if(renewBoard)
{
RenewGrid();
renewBoard = false;
}
}
void Update()
{
CheckGrid();
if (Input.GetMouseButtonDown(0))
{
Ray ray = Camera.main.ScreenPointToRay (Input.mousePosition); //casts a ray from mouse position
RaycastHit2D hit = Physics2D.GetRayIntersection (ray, 1000); //tests for ray hit
if (hit)
{
tile1 = hit.collider.gameObject; //changes tile1 null to the gameObject who's collider was hit
}
}
// if mouse button up detected after an initial tile has been hit with ray
else if (Input.GetMouseButtonUp(0) && tile1)
{
Ray ray = Camera.main.ScreenPointToRay (Input.mousePosition);
RaycastHit2D hit = Physics2D.GetRayIntersection (ray, 1000);
if (hit)
{
tile2 = hit.collider.gameObject; //changes tile2 nulle to the gameObject who's collider was hit
}
if (tile1 && tile2) //If we has two tile values clicked, swap them
{
//check to see that distance of clicked tiles is not greater than 1 tile
int horzDist = (int)Mathf.Abs (tile1.transform.position.x - tile2.transform.position.x);
int vertDist = (int)Mathf.Abs (tile1.transform.position.y - tile2.transform.position.y);
if (horzDist == 1^vertDist == 1) // X-OR Statment, IF 1 , OR 1, but NOT BOTH
{
//get tile 1's array position
Tile temp = tiles [(int)tile1.transform.position.x, (int)tile1.transform.position.y];
//change tile 1's array position to now be tile 2's array position
tiles [(int)tile1.transform.position.x, (int)tile1.transform.position.y] =
tiles [(int)tile2.transform.position.x, (int)tile2.transform.position.y];
//change tile 2's array position to now be tile 1's old array position
tiles [(int)tile2.transform.position.x, (int)tile2.transform.position.y] = temp;
Vector3 tempPos = tile1.transform.position; //get tile 1's GameObject position
tile1.transform.position = tile2.transform.position; //change tile 1 to tile 2's GameObject position
tile2.transform.position = tempPos; //change tile 2 to tile 1's GameObject position
//reset clicked tiles
tile1 = null;
tile2 = null;
}
else
{
GetComponent<AudioSource>().Play(); // Play error sound when illegal swap attempted
}
}
}
}
}
されている必要があります - しかし、あなたは 'C使用している - 1 ':'場合(タイル[C、R] = NULL &&タイルを! [c - 1、r]!= null) '' c 'が0の場合、それは 'tiles [-1、r]'を使うことになりますが、これは無効です。 –
私は彼が '[c、r - 1]'を置いて '[c-1、r]'を誤って '2番目の' 'CheckGrid'メソッドに入れたいと思っていたチュートリアルで、 double for loop) – CNuts
私はこれを理解しており、それを指摘してくれてありがとう。私に混乱を招くことは、整数値を2や3のように変更しても、同じエラーが発生します。現時点では、私のスキル範囲を超えてデバッグするだけです。 –