The question is answered, right answer was accepted
ArgumentOutOfRangeException: Argument is out of range. Parameter name: index
Receiving the following error when attempting to touch an GUI keys (will be taking GUI keys out later):
ArgumentOutOfRangeException: Argument is out of range. Parameter name: index System.Collections.Generic.List`1[System.Collections.Generic.List`1[Tile]].get_Item (Int32 index) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Collections.Generic/List.cs:633) GameManager.removeTileHighlights () (at Assets/scripts/GameManager.cs:97) UserPlayer.TurnOnGUI () (at Assets/scripts/UserPlayer.cs:53) GameManager.OnGUI () (at Assets/scripts/GameManager.cs:50)
The line being referenced in GameManager is: if (!map[j][i].impassible) map[j][i].visual.transform.GetComponent().materials[0].color = Color.white; And: if (players[currentPlayerIndex].HP > 0) players[currentPlayerIndex].TurnOnGUI();
UserPlayer code is: GameManager.instance.removeTileHighlights();
GameManager.cs
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Tiled2Unity;
public class GameManager : MonoBehaviour {
public static GameManager instance;
public GameObject gridBox;
public GameObject nobj;
public UserPlayer Prefab;
public TiledMap theTiles;
public List <List<Tile>> map = new List<List<Tile>>();
public List <Player> players = new List<Player>();
public int currentPlayerIndex = 0;
public float gridSize = 0.32f;
public bool isBattle;
void Awake() {
instance = this;
}
void Start() {
generateMap();
generatePlayers();
}
void Update() {
if (!isBattle) {
destroyTiles ();
}
//Debug.Log (map);
if (players[currentPlayerIndex].HP > 0) players[currentPlayerIndex].TurnUpdate();
else nextTurn();
}
void OnGUI () {
if (players[currentPlayerIndex].HP > 0) players[currentPlayerIndex].TurnOnGUI();
}
public void nextTurn() {
if (currentPlayerIndex + 1 < players.Count) {
currentPlayerIndex++;
}
else {
currentPlayerIndex = 0;
}
}
public void highlightTilesAt(Vector2 originLocation, Color highlightColor, int distance) {
highlightTilesAt(originLocation, highlightColor, distance, true);
}
public void highlightTilesAt(Vector2 originLocation, Color highlightColor, int distance, bool ignorePlayers) {
List <Tile> highlightedTiles = new List<Tile>();
if (ignorePlayers) highlightedTiles = TileHighlight.FindHighlight(map[(int)originLocation.x][(int)originLocation.y], distance, highlightColor == Color.red);
else highlightedTiles = TileHighlight.FindHighlight(map[(int)originLocation.x][(int)originLocation.y], distance, players.Where(x => x.gridPosition != originLocation).Select(x => x.gridPosition).ToArray(), highlightColor == Color.red);
foreach (Tile t in highlightedTiles) {
t.visual.transform.GetComponent<Renderer>().materials[0].color = highlightColor;
}
}
public void removeTileHighlights() {
for (int i = 0; i < theTiles.NumTilesHigh; i++) {
for (int j = 0; j < theTiles.NumTilesWide; j++) {
if (!map[j][i].impassible) map[j][i].visual.transform.GetComponent<Renderer>().materials[0].color = Color.white;
}
}
}
void generateMap() {
for (int i = 0; i < theTiles.NumTilesHigh; i++) {
List <Tile> row = new List<Tile>();
for (int j = 0; j < theTiles.NumTilesWide; j++) {
//nobj = (GameObject)GameObject.Instantiate (gridBox);
//nobj.transform.position = new Vector2 (gridBox.transform.position.x + (gridSize * j), gridBox.transform.position.y + (0.32f * i));
//nobj.name = j + "," + i;
Tile tile = GameObject.Instantiate(gridBox).GetComponent<Tile>();
tile.gridPosition = new Vector2 (j, i);
tile.name = j + "," + i;
tile.transform.position = new Vector2 (gridBox.transform.position.x + (gridSize * j), gridBox.transform.position.y + (0.32f * i));
tile.setType(TileType.Normal);
row.Add (tile);
tile.gameObject.transform.parent = gridBox.transform.parent;
tile.gameObject.SetActive (true);
}
map.Add (row);
}
}
void destroyTiles() {
for (int i = 0; i < theTiles.NumTilesHigh; i++) {
for (int j = 0; j < theTiles.NumTilesWide; j++) {
Destroy (GameObject.Find (j + "," + i));
//Debug.Log (i + "," + j);
}
}
}
public void moveCurrentPlayer(Tile destTile) {
if (destTile.visual.transform.GetComponent<Renderer>().materials[0].color != Color.white && !destTile.impassible && players[currentPlayerIndex].positionQueue.Count == 0) {
removeTileHighlights();
players[currentPlayerIndex].moving = false;
foreach(Tile t in TilePathFinder.FindPath(map[(int)players[currentPlayerIndex].gridPosition.x][(int)players[currentPlayerIndex].gridPosition.y],destTile, players.Where(x => x.gridPosition != destTile.gridPosition && x.gridPosition != players[currentPlayerIndex].gridPosition).Select(x => x.gridPosition).ToArray())) {
players[currentPlayerIndex].positionQueue.Add(map[(int)t.gridPosition.x][(int)t.gridPosition.y].transform.position + 1.5f * Vector3.up);
Debug.Log("(" + players[currentPlayerIndex].positionQueue[players[currentPlayerIndex].positionQueue.Count - 1].x + "," + players[currentPlayerIndex].positionQueue[players[currentPlayerIndex].positionQueue.Count - 1].y + ")");
}
players[currentPlayerIndex].gridPosition = destTile.gridPosition;
} else {
Debug.Log ("destination invalid");
destTile.visual.transform.GetComponent<Renderer>().materials[0].color = Color.cyan;
}
}
public void generatePlayers() {
UserPlayer player;
GameObject thePlayer;
Transform theStart;
player = GameObject.FindWithTag("Player").GetComponent<UserPlayer>();
thePlayer = GameObject.FindWithTag ("Player");
theStart = GameObject.Find ("15,3").GetComponent<Transform> ();
player.gridPosition = new Vector2(theStart.transform.position.x,theStart.transform.position.y);
thePlayer.transform.position = theStart.transform.position;
players.Add(player);
player = GameObject.Instantiate(GameObject.FindWithTag("Player").GetComponent<UserPlayer>());
theStart = GameObject.Find ("15,2").GetComponent<Transform> ();
player.gridPosition = new Vector2 (theStart.transform.position.x, theStart.transform.position.y);
player.transform.position = theStart.transform.position;
players.Add (player);
}
public void attackWithCurrentPlayer(Tile destTile) {
if (destTile.visual.transform.GetComponent<Renderer>().materials[0].color != Color.white && !destTile.impassible) {
Player target = null;
foreach (Player p in players) {
if (p.gridPosition == destTile.gridPosition) {
target = p;
}
}
if (target != null) {
//Debug.Log ("p.x: " + players[currentPlayerIndex].gridPosition.x + ", p.y: " + players[currentPlayerIndex].gridPosition.y + " t.x: " + target.gridPosition.x + ", t.y: " + target.gridPosition.y);
// if (players[currentPlayerIndex].gridPosition.x >= target.gridPosition.x - 1 && players[currentPlayerIndex].gridPosition.x <= target.gridPosition.x + 1 &&
// players[currentPlayerIndex].gridPosition.y >= target.gridPosition.y - 1 && players[currentPlayerIndex].gridPosition.y <= target.gridPosition.y + 1) {
players[currentPlayerIndex].actionPoints--;
removeTileHighlights();
players[currentPlayerIndex].attacking = false;
//attack logic
//roll to hit
//bool hit = Random.Range(0.0f, 1.0f) <= players[currentPlayerIndex].attackChance - target.evade;
//if (hit) {
//damage logic
//int amountOfDamage;// = Mathf.Max(0, (int)Mathf.Floor(players[currentPlayerIndex].damageBase + Random.Range(0, players[currentPlayerIndex].damageRollSides)) - target.damageReduction);
//target.HP -= amountOfDamage;
// Debug.Log(players[currentPlayerIndex].playerName + " successfuly hit " + target.playerName + " for " + amountOfDamage + " damage!");
//} else {
// Debug.Log(players[currentPlayerIndex].playerName + " missed " + target.playerName + "!");
//}
// }
}
} else {
Debug.Log ("destination invalid");
}
}
}
UserPlayer.cs
using UnityEngine;
using System.Collections;
public class UserPlayer : Player {
// Use this for initialization
void Start () {
}
// Update is called once per frame
public override void Update () {
if (GameManager.instance.players[GameManager.instance.currentPlayerIndex] == this) {
//transform.GetComponent<Renderer>().material.color = Color.green;
} else {
//transform.GetComponent<Renderer>().material.color = Color.white;
}
base.Update();
}
public override void TurnUpdate ()
{
//highlight
//
//
if (positionQueue.Count > 0) {
transform.position += (positionQueue[0] - transform.position).normalized * moveSpeed * Time.deltaTime;
if (Vector3.Distance(positionQueue[0], transform.position) <= 0.1f) {
transform.position = positionQueue[0];
positionQueue.RemoveAt(0);
if (positionQueue.Count == 0) {
actionPoints--;
}
}
}
base.TurnUpdate ();
}
public override void TurnOnGUI () {
float buttonHeight = 50;
float buttonWidth = 150;
Rect buttonRect = new Rect(0, Screen.height - buttonHeight * 3, buttonWidth, buttonHeight);
//move button
if (GUI.Button(buttonRect, "Move")) {
if (!moving) {
GameManager.instance.removeTileHighlights();
moving = true;
attacking = false;
GameManager.instance.highlightTilesAt(gridPosition, Color.blue, movementPerActionPoint, false);
} else {
moving = false;
attacking = false;
GameManager.instance.removeTileHighlights();
}
}
//attack button
buttonRect = new Rect(0, Screen.height - buttonHeight * 2, buttonWidth, buttonHeight);
if (GUI.Button(buttonRect, "Attack")) {
if (!attacking) {
GameManager.instance.removeTileHighlights();
moving = false;
attacking = true;
GameManager.instance.highlightTilesAt(gridPosition, Color.red, attackRange);
} else {
moving = false;
attacking = false;
GameManager.instance.removeTileHighlights();
}
}
//end turn button
buttonRect = new Rect(0, Screen.height - buttonHeight * 1, buttonWidth, buttonHeight);
if (GUI.Button(buttonRect, "End Turn")) {
GameManager.instance.removeTileHighlights();
actionPoints = 2;
moving = false;
attacking = false;
GameManager.instance.nextTurn();
}
base.TurnOnGUI ();
}
}
Answer by Sloth57 · Mar 03, 2017 at 01:26 AM
The issue was due to the i and j being swapped incorrectly for line 97. I ran a debug on map[47][31] (The highest numbers it could have been) and found out they were out of range. I swapped the two around and everything came back with no errors.
Your "outer list" seems to contain "rows" so it's index represents the y-coordinate but you pass an x-coordinate as first index. You should make yourself clear how you actually store your data in your Lists.
This question is a pure debugging question so it should have been posted in the help room. Even this "answer" answers your original question, it should not contain a follow up question. And when you post a follow up question it should be more clear. "Now I get an error ...".
I'll move this question into the Help Room.
Thanks, I was actually going to come back and mark this as an answer and then close the issue. Still going to do that. Figured out most of it was related to things being set incorrectly. Need to rewrite some of the code anyway.
Answer by Scoutas · Mar 02, 2017 at 09:31 PM
When creating an if loop, theTiles.NumTilesHigh
, theTiles is not instantiated, but I assume that it has static or const variables inside of them, that gives out the number for you. If it doesn't - find a way to instantiate it.
If it does, then it's a problem with your list. THe number that theTiles.NumTilesHigh
gives out is too big. Your nested list map
doesn't have anything assigned to those indexes that you are passing through. e.g. If your list has 2 objects, passing map[2]
tries to get the third object and it fails. So basically the problem is most likely here.