Hi, i’m making an Invetory GUI system from one game and i have this problem.
IndexOutOfRangeException: Array index is out of range. Position.Controller.GetObjectsInBag(Int32 t) (at Assets/Scripts/Inventory/PositionController.js 105)… (etc)
And the line of the error is
return objectsInBag[t];
of the function
function GetObjectsInBag(t: int) { return objectsInBag[t]; }
This is the script i’m using for
var mouseTextureHandler : MouseTextureHandling;
private var buttonClicked : boolean = false; //mira si el boton está pinchado
private var objAttached : boolean = false; //verdadero cuando un objeto ha sido seleccionado del inventario
private var posBags : Vector2[]; //posiciones en la pantalla donde ban a estar situadas las bolsas
private var flagAvailable : Array;
private var indexBags : int;
private var toggleAllBags : boolean = false;
private var objectsInBag : GameObject[]; //representa todos los objetos en la bolsa.
private var lastSlotUsed : int = -1; // dice cual ha sido el ultimo slot pinchado
private var slotMovedFlag : boolean = false; //flag to control movement inside the bag array
function Start()
{
objectsInBag = new GameObject[64]; //64 porque hay 4 bolsas y cada una tiene 16 espacios.
flagAvailable = new Array();
posBags = [Vector2(195,260), Vector2(195, 465), Vector2(385,260), Vector2(385,465)];
for( var i = 0; i < posBags.length; i++)
{
flagAvailable.Push(true);
}
indexBags = 0;
}
function Update() // ESTA FUNCION SE UTILIZA PARA QUE AL PULSAR SHIFT + B SE ABRAN Y SE CIERREN TODAS LAS BOLSAS
{
if(Input.GetKey(KeyCode.LeftShift) Input.GetKeyDown(KeyCode.B)) //Pulsado Shift + B
{
for(var child : Transform in transform)
{
if(child.GetComponent(InventoryGrid) == null)
{
break;
}
if(toggleAllBags)
{
child.GetComponent(InventoryGrid).HideBag();
}
else
{
if(!child.GetComponent(InventoryGrid).BagIsBeingDisplayed()) //asegurarse que la mochila no esta abierta
{
child.GetComponent(InventoryGrid).ShowBag();
}
}
}
if(toggleAllBags)
toggleAllBags = false;
else
toggleAllBags = true;
}
}
//devuelve la posicion que está disponible para mostrar en la bolsa seleccionada
function GetPositionAvailable()
{
var found : boolean = false;
for(indexBags = 0; indexBags < flagAvailable.length; indexBags++)
{
if(flagAvailable[indexBags])
{
found = true;
break;
}
}
if(!found)
{
Debug.Log("ERROR: por favor añade mas posiciones en el array posBags. ");
return;
}
flagAvailable[indexBags] = false;
return Vector3(posBags[indexBags].x , posBags[indexBags].y, indexBags);
}
function FreePosition(t: int)
{
flagAvailable[t] = true;
}
function SaveObjectInInventory(obj : GameObject)
{
for(var i : int = 0; i < objectsInBag.length; i++)
{
if(objectsInBag[i] == null)
{
objectsInBag[i] = obj;
obj.transform.localPosition = Vector3.zero;
obj.active = false;
obj.transform.parent = transform;
return;
}
}
}
function GetObjectsInBag(t : int)
{
return objectsInBag[t];
}
function SetObjectInBag(t : int, obj : GameObject)
{
objectsInBag[t] = obj;
}
function SetLastSlotUsed(t : int)
{
lastSlotUsed = t;
}
function GetLastSlotUsed()
{
return lastSlotUsed;
}
function SetSlotMovedFlag(val : boolean)
{
slotMovedFlag = val;
}
function GetSlotMovedFlag()
{
return slotMovedFlag;
}
function GetButtonClicked()
{
return buttonClicked;
}
function SetButtonClicked(val : boolean)
{
buttonClicked = val;
}
function GetObjectAttached()
{
return objAttached;
}
function SetObjAttached (val : boolean)
{
objAttached = val;
}
i think i dont really understand that (sorry for my english by the way)
GetObjectsInBag is the array where the objets are going to be save, when i click one object, it desapear from the screen but in the debug mode i can see that it is in the first position of this array.
Thanks!!!
In your Start you assign objectsInBag to be an array of size 64:
objectsInBag = new GameObject[64];
That means it has elements from 0 to 63 (64 entries but they start at 0). So if you try to access any entry outside of the range of 0-63, then it throws this “array index is out of range” error.
oh yes, i figured that is the problem but i don’t know which par of the code is trying to do that :s
EDIT: i think the -1 is invalid no? why is trying to acces that position?
Yeah, the -1 is invalid. The code you posted isn’t the code that calls GetObjectsInBag. I suggest you go through your game and find all the places that call the GetObjectsInBag function. If you have more than one place, put a Debug.Log statement before you call it with something like:
Debug.Log(“Calling GetObjectsInBag A”);
Then the second place that you find that calls it put:
Debug.Log(“Calling GetObjectsInBag B”);
Then the third place:
Debug.Log(“Calling GetObjectsInBag C”);
And so on. Then when you look at your log again, you’ll see something like:
Calling GetObjectsInBag B
Accessing Object index: -1
Then that way you know where it is that you’re passing in the wrong value. From there you can trace the logic back and see how exactly you end up with -1. If you can’t figure it out, try posting the calling code and we can take a look at it.
You should post your source code for the other people here.
I tried explaining the crux of the problem, but maybe they can do a better job articulating it and finding an exact solution to it.
EDIT: once he posts it, I think it has to do with the fact that “LastSlotUsed” is -1 if there was no slot used yet. However, in the MoveSlot function, that -1 is then passed into GetObjectsInBag which naturally complains about getting object -1.
var bagName : String = "Pon un nombre a la bolsa";
var bagBtnName : String = "Nombre del boton de la bolsa";
var posBagBtn : Vector2 = Vector2(50,50); //posicion del boton de la bolsa
var slotSize : float = 40; // Este es el tamaño que va a tener la bolsa
var spacingBetweenSlots : float = 5;
var defaultTextureSlot : Texture;
var bagNumber : int; // dice que bolsa está enlazada a esta transformación.
private var numSlots = 16;
private var offsetBag : int; //eso es cuanto se va a mover el index lel prents bag array
private var showBag : boolean = false; //muestra o no muestra esta bolsa.
private var bagPos : Vector2;
private var indexOnController : int; //Representa un index para posicionar la bolsa.
private var tmpTexture : Texture;
private var ctrl : PositionController;
function Start ()
{
offsetBag = bagNumber * numSlots;
ctrl = transform.parent.GetComponent(PositionController); //el parent es para el inventory, que es el padre de las bolsas
indexOnController = 0;
}
function OnGUI ()
{
if(GUI.Button(Rect(Screen.width - posBagBtn.x, Screen.height - posBagBtn.y, slotSize,slotSize), bagBtnName)) //Pinta un boton, rectángulo.
{
ToggleBag();
}
if(showBag)
{
Bag(bagPos.x, bagPos.y, 185,200);
}
}
function ToggleBag ()
{
if(showBag)
{
HideBag();
}
else
{
ShowBag();
}
}
function HideBag()
{
showBag = false;
ctrl.FreePosition(indexOnController);
}
function ShowBag()
{
showBag = true;
var info : Vector3 = ctrl.GetPositionAvailable();
indexOnController = info.z;
bagPos = Vector2(info.x, info.y);
}
function BagIsBeingDisplayed()
{
return showBag;
}
function Bag(posX : float, posY : float, sX : float, sY : float){
GUI.BeginGroup(Rect(Screen.width - posX, Screen.height - posY, sX, sY));
GUI.Box(Rect(0,0, sX, sY), bagName);
for(var i = 0; i < 4; i++)
{
for(var j = 0; j < 4; j++)
{
if(ctrl.GetObjectsInBag(offsetBag + (4*i)+j) == null) //No hay objeto en ese SLOT, se pone la textura por defecto
{
tmpTexture = defaultTextureSlot;
}
else
{
tmpTexture = ctrl.GetObjectsInBag(offsetBag+(4*i)+j).GetComponent(ObjectInfo).iconTexture; //pone la textura del objeto
}
if(Input.GetMouseButtonDown(0))
{
ctrl.SetButtonClicked(false);
}
if(GUI.Button(Rect(slotSize*j + spacingBetweenSlots*(j+1), slotSize*i + spacingBetweenSlots*(i+1) + 15, slotSize, slotSize), tmpTexture))
{
ctrl.SetButtonClicked(true);
if(ctrl.GetObjectsInBag(offsetBag+(4*i)+j) != null) //poner la textura a nuestro cursor del raton
{
ctrl.mouseTextureHandler.SetCursor(ctrl.GetObjectsInBag(offsetBag+(4*i)+j).GetComponent(ObjectInfo).iconTexture);
ctrl.SetObjAttached(true);
}
MoveSlot(offsetBag + (4*i)+j);
}
}
}
GUI.EndGroup();
}
function MoveSlot(indSlot : int){
if(ctrl.GetObjectsInBag(indSlot) == null !ctrl.GetSlotMovedFlag()){//case when we click in a new empty space (we are moving our item to a new one)
ctrl.SetObjectInBag(indSlot, ctrl.GetObjectsInBag(ctrl.GetLastSlotUsed()));//assign the object to a new slot.
ReleaseSlot(ctrl.GetLastSlotUsed());
ctrl.SetSlotMovedFlag(true);
ctrl.mouseTextureHandler.ReleaseCursorIcon();
ctrl.SetObjAttached(false);
} else if(ctrl.GetObjectsInBag(indSlot) != null ctrl.GetObjectsInBag(ctrl.GetLastSlotUsed()) != null !ctrl.GetSlotMovedFlag()){//swap two non-empty slots.
var tmpObj : GameObject = ctrl.GetObjectsInBag(indSlot);
ctrl.SetObjectInBag(indSlot, ctrl.GetObjectsInBag(ctrl.GetLastSlotUsed()));
ctrl.SetObjectInBag(ctrl.GetLastSlotUsed(),tmpObj);
ctrl.SetSlotMovedFlag(true);
ctrl.mouseTextureHandler.ReleaseCursorIcon();
ctrl.SetObjAttached(false);
} else {
ctrl.SetSlotMovedFlag(false);
}
ctrl.SetLastSlotUsed(indSlot);
}
function ReleaseSlot(index : int)
{
ctrl.SetObjectInBag(index, null);
}
My best guess is that there is a bug in the code or something has been missed out.
private var lastSlotUsed : int = -1; // dice cual ha sido el ultimo slot pinchado
and it’s in this function somewhere.
function MoveSlot(indSlot : int){
if(ctrl.GetObjectsInBag(indSlot) == null !ctrl.GetSlotMovedFlag()){//case when we click in a new empty space (we are moving our item to a new one)
ctrl.SetObjectInBag(indSlot, ctrl.GetObjectsInBag(ctrl.GetLastSlotUsed()));//assign the object to a new slot.
ReleaseSlot(ctrl.GetLastSlotUsed());
ctrl.SetSlotMovedFlag(true);
ctrl.mouseTextureHandler.ReleaseCursorIcon();
ctrl.SetObjAttached(false);
} else if(ctrl.GetObjectsInBag(indSlot) != null ctrl.GetObjectsInBag(ctrl.GetLastSlotUsed()) != null !ctrl.GetSlotMovedFlag()){//swap two non-empty slots.
var tmpObj : GameObject = ctrl.GetObjectsInBag(indSlot);
ctrl.SetObjectInBag(indSlot, ctrl.GetObjectsInBag(ctrl.GetLastSlotUsed()));
ctrl.SetObjectInBag(ctrl.GetLastSlotUsed(),tmpObj);
ctrl.SetSlotMovedFlag(true);
ctrl.mouseTextureHandler.ReleaseCursorIcon();
ctrl.SetObjAttached(false);
} else {
ctrl.SetSlotMovedFlag(false);
}
ctrl.SetLastSlotUsed(indSlot);
}
The only strange thing is that if get the objects in the bag, and i press the first one, nothing happends untill i don press it the second time…
or if i press other object in the bag, it switch with the first one, than y can selec whatever i want and move it wherever i want