- Home /
Public variable giving me "null reference exception"
Hey, everyone. I'm working on an inventory code, but I haven't gotten far because of a slight issue. Whenever I try to access my "items[]" variable(which is a separate class on another script with vars for an icon, a rect, an index, and an item(yet another script)), it gives me "Null reference exception: object reference not set to an instance of an object" and forfeits the function. I have no idea whats going on. Here's the inventory code:
var headSlotItemType : ItemType;
var handLSlotItemType : ItemType;
var handRSlotItemType : ItemType;
var shirtSlotItemType : ItemType;
var pantsSlotItemType : ItemType;
var shoeSlotItemType : ItemType;
var headPos : Transform;
var handLPos : Transform;
var handRPos : Transform;
var slotSize : float = 50.0;
var slotSpacing : float = 10.0;
var headSlotPos : Vector2 = Vector2(195, 40);
var handLSlotPos : Vector2 = Vector2(50, 120);
var handRSlotPos : Vector2 = Vector2(195, 120);
var shirtSlotPos : Vector2 = Vector2(10, 190);
var pantSlotPos : Vector2 = Vector2(70, 190);
var shoeSlotPos : Vector2 = Vector2(130, 190);
var offset : Vector2 = Vector2(5, 15);
var backgroundGUIStyle : GUIStyle;
var textGUIStyle : GUIStyle;
var slotGUIStyle : GUIStyle;
var boxGUIStyle : GUIStyle;
var toggleKeys : KeyCode[] = [KeyCode.I];
var invWindowID : int = 0;
var defaultSlotIcon : Texture2D;
var commonColor : Color;
var uncommonColor : Color;
var rareColor : Color;
var items : ItemInfo[];
private var rects : Rect[];
private var curSelectedItemInfo : ItemInfo;
private var showInv : boolean = true;
private var nextAvailableSlot : int;
private var player : Transform;
private var full : boolean;
private var windowRect : Rect;
private var characterRect : Rect;
function Awake() {
items = new ItemInfo[26];
player = GameObject.FindWithTag("Player").transform;
invDisplay = GetComponent(InventoryDisplay);
rects = new Rect[26];
SetRects();
}
function SetRects() {
//The Individual Slot Rects
var i : int;
for(y = 0; y < 4; y++) {
for(x = 0; x < 5; x++) {
rects[i] = new Rect(slotSize*x + slotSpacing*(x) + offset.x, slotSize*y + slotSpacing*(y) + offset.y, slotSize, slotSize);
i++;
}
}
//The Window Rect
windowRect = new Rect(10, 10, 300, 500);
//The Character Picture Rect
characterRect = new Rect(5, 40, 290, 200);
//Head Slot Rect
rects[20] = new Rect(headSlotPos.x, headSlotPos.y, slotSize, slotSize);
//Left Hand Slot Rect
rects[21] = new Rect(handLSlotPos.x, handLSlotPos.y, slotSize, slotSize);
//Right Hand Slot Rect
rects[22] = new Rect(handRSlotPos.x, handRSlotPos.y, slotSize, slotSize);
//Shirt slot Rect
rects[23] = new Rect(shirtSlotPos.x, shirtSlotPos.y, slotSize, slotSize);
//Pant Slot Rect
rects[24] = new Rect(pantSlotPos.x, pantSlotPos.y, slotSize, slotSize);
//Shoe Slot Rect
rects[25] = new Rect(shoeSlotPos.x, shoeSlotPos.y, slotSize, slotSize);
for(i = 0; i < 26; i++) {
items[i].rectInWindow = rects[i];
}
}
function PickUpItem(newItem : ItemInfo) {
CalculateNextAvailableSlot();
items[nextAvailableSlot] = newItem;
newItem.relativeItem.gameObject.transform.parent = transform;
newItem.relativeItem.transform.position = transform.position;
newItem.relativeItem.transform.rotation = transform.rotation;
newItem.relativeItem.SetEquipped(true);
newItem.relativeItem.gameObject.SetActiveRecursively(false);
}
function CalculateNextAvailableSlot()
{
var index : int;
for(i = 0; i < items.length; i++)
{
if(items[i].relativeItem == null) {
index = i;
break;
}
}
nextAvailableSlot = index;
}
function GetNextAvailableSLot() : int {
return nextAvailableSlot;
}
function SetNextAvailableSlot(i : int) {
nextAvailableSlot = i;
}
function OnGUI() {
if(showInv) {
windowRect = GUI.Window(invWindowID, windowRect, InventoryWindow, "Inventory");
}
}
function InventoryWindow(id : int) {
GUI.DragWindow(Rect(0, 0, 10000, 1000));
}
and here's the code with the item info class on it:
enum ItemType
{
Consumable,
Weapon,
Armor,
Clothing
}
enum Rarity
{
Common,
Uncommon,
Rare
}
class ItemInfo {
var iconTexture : Texture2D;
var indexInArray : int;
var relativeItem : Item;
var rectInWindow : Rect;
}
Does anyone know what I'm doing wrong? All help would be appreciated. Thanks! :)
Answer by Bunny83 · Aug 22, 2011 at 03:15 PM
I guess you set the item array in the inspector? In this case you shouldn't create the array yourself.
this line will recreate the whole array and deletes the old one:
items = new ItemInfo[26];
Furthermore all items in this new array will be null.
Unity creates the array and the containing classes for you when you edit the array in the inspector.
Just remove the line above and it should work ;)
Well, i intend to eventually make that one private, so that's why i make a new one in the awake function.
But where do you create the ItemInfo objects?
this line:
items = new ItemInfo[26];
only creates the array with 26 references, but they all points to "null". You have to create each item.
for (var i = 0; i < items.Length; i++)
items[i] = new ItemInfo();
Answer by roamcel · Aug 22, 2011 at 12:24 PM
For what I understand of your code, since you're not retrieving ItemInfo from a component, you need to declare its class as STATIC to be able to use it. Unfortunately I don't know the js syntax for static but on c# you write
public static class ItemInfo {
...
unfortunatly, i tried that. I also tried doing something similar to what the bootcamp demo had, Weapon $$anonymous$$ey Binder i believe it was called. neither of those worked. Any other ideas?
@roamcel: Sorry but that's not true. If you turn the ItemInfo class into a static class, all members have to be static as well. You can't even create instances of static classes.
He used the class absolutely right.
You're right. I'm sorry I mistook javascript's lack of explicit 'monobehavior' with an attempt to create a static class.