hi i have an issue iwth my inventory script …all work fine except that wheni click on a emply slot my test game stops and i have the following error on console
ArgumentOutOfRangeException: Argument is out of range.
Parameter name: index
System.Collections.Generic.List`1[UnityEngine.GameObject].get_Item (Int32 index) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Collections.Generic/List.cs:633)
Inventory.OnGUI () (at Assets/Vaijk Inventory System/Scripts/Inventory/Inventory.cs:189)
this is my inventory script
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class Inventory : MonoBehaviour
{
public int verticalSlots;
public int horizontalSlots;
public float slotSizeX;
public float slotSizeY;
[HideInInspector]
public bool showInventory;
[HideInInspector]
public bool userHasOption = false;
public Texture2D emptySlotTexture;
public KeyCode inventoryInput;
public GUISkin guiSkin;
public List<Slot> inventory;
private bool dragging = false;
private GameObject equipedObject = null;
private Vector2 windowPosition = Vector2.zero;
private Vector2 windowSize = Vector2.zero;
private Vector2 clickMousePosition = Vector2.zero;
private Slot dragSlot = new Slot();
private Slot receiver = new Slot();
private PlayerInteraction playerInteraction = null;
// Represents an Inventory Slot.
public struct Slot
{
public int id; // Identifier used to find this Slot.
public int itemID;
// Returns the actual amount of Items inside this Slot.
public int stacks
{
get { return slotObjects.Count; }
}
// Returns if we have more then one Item inside this Slot.
public bool stackableSlot
{
get { return slotObjects.Count > 1; }
}
public List<GameObject> slotObjects;
public Texture2D slotTexture;
public Rect originalRect;
public Rect currentRect;
// Returns a bool indicating if this slots original Rect contains <cursorPosition>.
public bool Contains (Vector2 cursorPosition)
{
return this.originalRect.Contains(cursorPosition);
}
// Returns a bool indicating if this slot is outside the GUI Windows Rect.
public bool OutsideWindow (Vector2 windowPosition, Vector2 windowSize)
{
Rect windowRect = new Rect(windowPosition.x, windowPosition.y, windowSize.x, windowSize.y);
return !windowRect.Contains(Event.current.mousePosition);
}
}
private void OnValidate ()
{
if (verticalSlots < 1)
verticalSlots = 1;
if (horizontalSlots < 1)
horizontalSlots = 1;
if (slotSizeY < 1)
slotSizeY = 1;
if (slotSizeX < 1)
slotSizeX = 1;
}
private void Start ()
{
// Find our PlayerInteraction MonoBehaviour on our Player Camera GameObject.
playerInteraction = transform.Find("Camera").GetComponent<PlayerInteraction>();
// Inicialize our <inventory> List with a set <inventorySize> capacity.
inventory = new List<Slot>(horizontalSlots * verticalSlots);
// Calculate the <windowSize> based on the <slotSize> and the amount of slots.
windowSize = new Vector2(horizontalSlots * slotSizeX, verticalSlots * slotSizeY);
// Calculate the <windowPosition> based on <windowSize>.
windowPosition = new Vector2((Screen.width - windowSize.x) / 2, (Screen.height - windowSize.y) / 2);
// Our current (X,Y) positions inside our GUI Window.
float currentX = windowPosition.x;
float currentY = windowPosition.y;
// Add an empty slot for each available slot in the <inventory>.
for (int i = 0; i < inventory.Capacity; i++)
{
Slot emptySlot = new Slot();
emptySlot.id = i;
emptySlot.itemID = 0;
emptySlot.slotObjects = new List<GameObject>();
emptySlot.slotTexture = emptySlotTexture;
emptySlot.originalRect = new Rect(currentX, currentY, slotSizeX, slotSizeY);
emptySlot.currentRect = emptySlot.originalRect;
// Move horizontally by <slotSize>.
currentX += slotSizeX;
// Check if we can fit another Slot horizontally.
if (currentX + slotSizeX > windowPosition.x + windowSize.x)
{
// If we cannot fit another slot horizontally then move vertically and
// reset our horizontal position.
currentX = windowPosition.x;
currentY += slotSizeY;
}
inventory.Add(emptySlot);
}
}
private void Update ()
{
// Show or hide this inventory.
if (Input.GetKeyDown(inventoryInput))
{
showInventory = !showInventory;
Cursor.visible = showInventory;
GetComponent<MouseRotation>().enabled = !showInventory;
transform.Find("Camera").GetComponent<MouseRotation>().enabled = !showInventory;
}
}
private void OnGUI ()
{
GUI.skin = guiSkin;
if (showInventory)
{
// The Inventory's Header.
GUI.Box(new Rect(windowPosition.x, windowPosition.y - 25, windowSize.x, 30), "Inventory");
// The Inventory's Window.
GUI.Box(new Rect(windowPosition.x, windowPosition.y, windowSize.x, windowSize.y), "");
for (int i = 0; i < inventory.Count; i++)
{
if (inventory*.stackableSlot)*
{
// If this slot is stackable then draw a label counting the amount of
// stacks and disable the ability to equip this stackable item.
string stackLabel = string.Format(“<size=20>{0}”, inventory*.stacks);*
// Stackable items are not equipable.
GUI.Button(inventory_.currentRect, inventory*.slotTexture);*_
// Only show the stack amount label is we have more then 1 item stacked.
if (inventory*.stacks > 0)*
GUI.Label(inventory*.currentRect, stackLabel);*
}
else
{
// If we click this Slot Button then equip the GameObject it holds.
if (GUI.Button(inventory_.currentRect, inventory*.slotTexture) && !userHasOption)
{_
_Item slotItem = inventory.slotObjects[0].GetComponent();*_
if (inventory*.slotObjects.Count > 0 && slotItem.usable)*
{
GameObject slotObject = inventory*.slotObjects[0];*
slotObject.SendMessage(“InventoryUse”, SendMessageOptions.DontRequireReceiver);
Destroy(inventory_.slotObjects[inventory*.slotObjects.Count - 1]);
inventory.slotObjects.RemoveAt(inventory.slotObjects.Count - 1);*_
if (inventory*.slotObjects.Count < 1)*
inventory = ResetSlot(inventory*);*
}
}
}
// If the mouse is inside this Slot then watch for dragging.
if (inventory*.Contains(Event.current.mousePosition) && !dragging)*
{
// If we click with the left mouse button set its click screen position;
if (Input.GetMouseButtonDown(0))
{
clickMousePosition = Event.current.mousePosition;
}
// If we clicked then moved our mouse that means we are dragging the slot.
if (Input.GetMouseButton(0) && Event.current.mousePosition != clickMousePosition)
{
// Prevent the Player from dragging empty slots.
if (inventory*.slotObjects.Count > 0)*
{
dragSlot = inventory*;*
dragging = true;
}
}
}
if (dragging)
{
if (Input.GetMouseButtonUp(0))
{
// If we released our left mouse button and the Slots Rect is
// outside the Window, then drop the item it contained.
if (dragSlot.OutsideWindow(windowPosition, windowSize))
{
if (dragSlot.slotObjects.Count > 0)
{
Item item = null;
if (dragSlot.stackableSlot)
{
// If we are a stackable Slot then we drop 1 of the stacked items.
if (dragSlot.slotObjects.Count == 1)
{
// If we only have 1 GameObject left then drop it and restore this
// slot to a normal empty slot.
item = dragSlot.slotObjects[0].GetComponent();
dragSlot = ResetSlot(dragSlot);
}
else
{
int lastItemIndex = dragSlot.slotObjects.Count - 1;
item = dragSlot.slotObjects[lastItemIndex].GetComponent();
dragSlot.slotObjects.RemoveAt(lastItemIndex);
}
}
else
{
// If the Slot we dragged out of the Window is not stackable
// then just drop the item it contained.
item = dragSlot.slotObjects[0].GetComponent();
dragSlot = ResetSlot(dragSlot);
if (equipedObject != null)
{
equipedObject.SetActive(false);
equipedObject = null;
}
}
item.DropItem();
// Since we are modifying this Slot inside the main foreach loop
// calling UpdateSlotData() would be extremelly slow due to a
// loop inside another loop.
inventory[inventory_.id] = inventory*;
}
}
else
{
// If we dropped the Item inside the Window, check what Slot we dropped*
// it upon._
for (int y = 0; y < inventory.Count; y++)
{
// If this instance is the itself then skip it.
if (inventory[y].id == dragSlot.id)
continue;
// If we found a Slot that contains the mouse then exchange
// Slot information from the to the
// and the to the .
if (inventory[y].Contains(Event.current.mousePosition))
{
receiver = inventory[y];
userHasOption = true;
break;
}
}
}
// If we got our left mouse button up return the
// to its original position.
dragSlot.currentRect = dragSlot.originalRect;
// Update the 's data.
UpdateSlotData(dragSlot);
// And since we released the left mouse button we are no longer dragging.
dragging = false;
break;
}
// If we are dragging then set the 's position to be the current
// mouse cursor’s position (Compensating for the offset).
dragSlot.currentRect.x = Event.current.mousePosition.x - 35;
dragSlot.currentRect.y = Event.current.mousePosition.y - 35;
// If the current slot being iterated is the then update its info.
if (inventory*.id == dragSlot.id)*
inventory[inventory.IndexOf(inventory*)] = dragSlot;*
}
}
if (userHasOption)
{
// Prompt the Player if he wants to create whatever the combination
// of both items can create or just exchange Slots.
if (receiver.slotObjects.Count == 0)
{
if (dragSlot.stackableSlot && dragSlot.stacks > 1)
{
Rect button1Rect = new Rect(Screen.width - windowPosition.x,
Screen.height - windowPosition.y - 80, 150, 40);
Rect button2Rect = new Rect(Screen.width - windowPosition.x,
Screen.height - windowPosition.y - 40, 150, 40);
if (GUI.Button(button1Rect, “Move Stack”))
{
receiver.itemID = dragSlot.itemID;
receiver.slotObjects = dragSlot.slotObjects;
receiver.slotTexture = dragSlot.slotTexture;
dragSlot.itemID = 0;
dragSlot.slotObjects = new List();
dragSlot.slotTexture = emptySlotTexture;
UpdateSlotData(receiver);
UpdateSlotData(dragSlot);
userHasOption = false;
}
if (GUI.Button(button2Rect, “Seperate Stack”))
{
receiver.itemID = dragSlot.itemID;
receiver.slotObjects.Add(dragSlot.slotObjects[dragSlot.slotObjects.Count - 1]);
receiver.slotTexture = dragSlot.slotTexture;
dragSlot.slotObjects.RemoveAt(dragSlot.slotObjects.Count - 1);
UpdateSlotData(receiver);
UpdateSlotData(dragSlot);
userHasOption = false;
}
}
else
{
ExchangeSlots(dragSlot, receiver);
userHasOption = false;
}
}
else
{
Rect button1Rect = new Rect(Screen.width - windowPosition.x,
Screen.height - windowPosition.y - 120, 150, 40);
Rect button2Rect = new Rect(Screen.width - windowPosition.x,
Screen.height - windowPosition.y - 80, 150, 40);
Rect button3Rect = new Rect(Screen.width - windowPosition.x,
Screen.height - windowPosition.y - 40, 150, 40);
// GUI Button for combining 2 Slot items.
CraftingCombinations crafting = this.GetComponent();
string craftableItem = “”;
int newItemID = 0;
foreach (CraftingCombinations.ItemCombination combination in crafting.itemCombinations)
{
int combinationSum = (combination.itemID1 * 10) + combination.itemID2;
int inventorySum = (dragSlot.itemID * 10) + receiver.itemID;
if (combinationSum == inventorySum)
{
craftableItem = combination.name;
newItemID = combinationSum;
}
}
if (newItemID != 0)
{
// GUI Button for crafting items.
if (GUI.Button(button3Rect, "Craft " + craftableItem))
{
GameObject craftedObject = Resources.Load(craftableItem);
GameObject craftedInstance = (GameObject)Instantiate(craftedObject);
craftedInstance.name = craftableItem;
CraftItem(craftedInstance, newItemID);
}
}
// GUI Button for swaping Slots.
if (GUI.Button(button2Rect, “Swap Items”))
{
ExchangeSlots(dragSlot, receiver);
userHasOption = false;
}
// GUI Button for stacking Slots.
if (receiver.itemID == dragSlot.itemID)
{
if (GUI.Button(button1Rect, “Stack Items”))
{
receiver.slotObjects.Add(dragSlot.slotObjects[dragSlot.slotObjects.Count - 1]);
dragSlot.slotObjects.RemoveAt(dragSlot.slotObjects.Count - 1);
if (dragSlot.slotObjects.Count < 1)
{
for (int i = 0; i < inventory.Count; i++)
{
if (inventory*.id == dragSlot.id)*
{
inventory = ResetSlot(inventory*);*
break;
}
}
}
userHasOption = false;
}
}
}
}
}
}
public void CraftItem (GameObject craftedObject, int newItemID)
{
Item craftedItem = craftedObject.GetComponent();
// Remove the item from the .
if (dragSlot.slotObjects.Count > 0)
{
Destroy(dragSlot.slotObjects[dragSlot.slotObjects.Count - 1]);
if (dragSlot.stacks > 1)
{
dragSlot.slotObjects.RemoveAt(dragSlot.slotObjects.Count - 1);
}
else
{
dragSlot = ResetSlot(dragSlot);
}
}
// Remove the item from the Slot.
if (receiver.slotObjects.Count > 0)
{
Destroy(receiver.slotObjects[receiver.slotObjects.Count - 1]);
if (receiver.stacks > 1)
{
receiver.slotObjects.RemoveAt(receiver.slotObjects.Count - 1);
}
else
{
receiver = ResetSlot(receiver);
}
craftedItem.PickupItem(this.transform);
if (InventoryHasSpace())
{
Slot slot = new Slot();
for (int i = 0; i < inventory.Count; i++)
{
slot = inventory*;*
if (slot.itemID == 0)
{
slot.itemID = newItemID;
slot.slotTexture = craftedItem.slotIcon;
slot.slotObjects.Add(craftedObject);
break;
}
}
UpdateSlotData(slot);
}
else
{
craftedItem.DropItem();
}
}
UpdateSlotData(receiver);
UpdateSlotData(dragSlot);
userHasOption = false;
}
public bool InventoryHasSpace()
{
foreach (Slot slot in inventory)
{
if (slot.slotObjects.Count == 0)
return true;
}
return false;
}
public void AddItem (Item item)
{
if (!InventoryHasSpace())
{
Debug.Log(“No available slots in inventory for " + item.name + " to be added.”);
return;
}
Slot editSlot = new Slot();
// If this item is stackable then find a Slot with its similar
// GameObject type and stack it, if there is none, just add it.
if (item.maxStackAmount > 1)
{
// Search for any stackable Slots with the same GameObject type as
// the one we want to add.
List stackableSlots = FindSlot(item.itemID);
if (stackableSlots.Count > 0)
{
foreach (Slot stackableSlot in stackableSlots)
{
if (stackableSlot.stacks < item.maxStackAmount)
{
// If we found a stackable Slot with the same GameObject type as
// the one we want to add, then add another stack to that slot.
// If this is the Slots first stack set it to stackable.
stackableSlot.slotObjects.Add(playerInteraction.currentObject);
editSlot = stackableSlot;
break;
}
}
if (editSlot.itemID == 0)
editSlot = AddToEmptySlot(item);
}
else
{
// If we do not already contain this GameObject type then just add it.
editSlot = AddToEmptySlot(item);
}
}
else
{
// If this item is not stackable then just add it to an empty Slot.
editSlot = AddToEmptySlot(item);
}
// Pickup the item we were interacting with.
item.PickupItem(this.transform);
// Update the actual inventory Slot.
UpdateSlotData(editSlot);
}
private Slot ResetSlot (Slot slot)
{
slot.itemID = 0;
slot.slotObjects = new List();
slot.slotTexture = emptySlotTexture;
return slot;
}
// Exchanges information between the and Slots.
private void ExchangeSlots(Slot sender, Slot receiver)
{
// Check if the has any information to exchange, otherwise
// there is no reason to exchange Nothing for Nothing.
if (sender.slotObjects.Count > 0)
{
Slot oldSender = sender;
// Change the 's information to the ones the Slot had.
sender.itemID = receiver.itemID;
sender.slotObjects = receiver.slotObjects;
sender.slotTexture = receiver.slotTexture;
// Change the 's information to the ones the had.
receiver.itemID = oldSender.itemID;
receiver.slotObjects = oldSender.slotObjects;
receiver.slotTexture = oldSender.slotTexture;
UpdateSlotData(sender);
UpdateSlotData(receiver);
}
}
// Finds the next available empty Slot.
private Slot FindSlot()
{
foreach (Slot slot in inventory)
{
if (slot.slotObjects.Count == 0)
return slot;
}
return new Slot();
}
// Finds the slot that contains a GameObject with the same
// type as the .
private List FindSlot(int objectID)
{
List foundSlots = new List();
foreach (Slot slot in inventory)
{
if (slot.itemID == objectID)
foundSlots.Add(slot);
}
return foundSlots;
}
// Finds the Slot inside the Inventory by using its id.
private void UpdateSlotData (Slot target)
{
for (int i = 0; i < inventory.Count; i++)
{
if (inventory*.id == target.id)*
inventory = target;
}
}
private Slot AddToEmptySlot (Item item)
{
Slot editSlot = FindSlot();
if (editSlot.slotObjects.Count == 0)
{
// Add the GameObject we were interacting with to the slot.
editSlot.slotObjects.Add(playerInteraction.currentObject);
editSlot.slotTexture = item.slotIcon;
editSlot.itemID = item.itemID;
}
return editSlot;
}
}
error is related to this part of the code i think
// If we click this Slot Button then equip the GameObject it holds.
if (GUI.Button(inventory_.currentRect, inventory*.slotTexture) && !userHasOption)
{*
**Item slotItem = inventory.slotObjects[0].GetComponent();**_
if (inventory*.slotObjects.Count > 0 && slotItem.usable)*
{
GameObject slotObject = inventory*.slotObjects[0];*
slotObject.SendMessage(“InventoryUse”, SendMessageOptions.DontRequireReceiver);
Destroy(inventory_.slotObjects[inventory*.slotObjects.Count - 1]);
inventory.slotObjects.RemoveAt(inventory.slotObjects.Count - 1);*_
if (inventory*.slotObjects.Count < 1)*
inventory = ResetSlot(inventory*);*
}
}
here the item script
using UnityEngine;
using System.Collections;
[RequireComponent(typeof(Rigidbody))]
public class Item : MonoBehaviour
{
public int itemID;
public int maxStackAmount;
public float interactTime;
public bool usable;
[HideInInspector]
public bool wasPlaced;
public Texture2D slotIcon;
private Renderer thisRenderer = null;
private Collider thisCollider = null;
private Inventory playerInventory = null;
private void OnValidate ()
{
if (itemID < 1)
itemID = 1;
if (maxStackAmount < 1)
maxStackAmount = 1;
if (interactTime < 1)
interactTime = 1;
}
private void Awake ()
{
thisRenderer = GetComponent();
thisCollider = GetComponent();
playerInventory = GameObject.FindObjectOfType();
}
public void PickupItem (Transform player)
{
// Set our parent as the Player’s Camera.
transform.parent = player.Find(“Camera”).Find(“Inventory Items”);
if (thisRenderer == null)
{
for (int i = 0; i < transform.childCount; i++)
transform.GetChild(i).GetComponent().enabled = false;
}
else
{
thisRenderer.enabled = false;
}
thisCollider.isTrigger = true;
}
public void DropItem ()
{
transform.position = transform.parent.position;
transform.rotation = transform.parent.rotation;
transform.parent = null;
if (thisRenderer == null)
{
for (int i = 0; i < transform.childCount; i++)
transform.GetChild(i).GetComponent().enabled = true;
}
else
{
thisRenderer.enabled = true;
}
thisCollider.isTrigger = false;
GetComponent().AddForce(transform.forward * 40, ForceMode.Force);
}
private void Interacting ()
{
if (!playerInventory.InventoryHasSpace())
return;
GameObject playerCamera = playerInventory.transform.FindChild(“Camera”).gameObject;
PlayerInteraction interaction = playerCamera.GetComponent();
interaction.interactTime = interactTime;
interaction.interactLabel = “Picking up…”;
}
private void Interacted ()
{
playerInventory.AddItem(this);
}
}
can please someone tell me where i wrong?
many thanks