- Home /
Having trouble iterating through an array of GameObjects of a certain type
I'm working on an inventory system, and I want it to be an array of gameobjects of type Item (a script that I have in my project). I have a gameobject in the scene with script Item.js, that has an itemName var defined, and the collision code to call the AddItem function in the Inventory script on the player with itself as the parameter. Here is the inventory script so far:
var inventory : Item[]; var inventoryLength : int = 16;
function Awake () { inventory = new Item[inventoryLength]; }
function OnGUI(){ for( var i = 0; i < inventory.length; i++ ){ var currentItem = inventory[i]; if(currentItem != null){ GUI.Label (Rect (30, (30*i), 120, 30), currentItem.itemName); } } }
function AddItem( item : Item ) { for( var i = 0; i < inventory.length; i++ ) { if( inventory[i] == null ) { inventory[i] = item; print(inventory[i].itemName); return; } }
}
Notice in the AddItem function I am printing the itemName var of the item being added upon collision after I inserted into the inventory. THAT is working. However, in my OnGUI function where I am trying to iterate through the inventory and print all the itemNames as labels, it is not doing anything. No errors, nothing. What am I doing wrong?
I didn't spot any errors in your code (although maybe someone else will). If you're still stuck on this though, I'd recommend adding some debug output in OnGUI() as well to try to deter$$anonymous$$e more specifically what's going wrong. ($$anonymous$$g., are all of the items 'null' in OnGUI()? Are the labels being rendered but not ending up being visible for some reason? Etc.)
Thanks Jesse. Inside my for loop in OnGUI(), I removed the null check and just drew the label. It works now! $$anonymous$$y only problem is that for every iteration through an index of the inventory array that is empty, it throws back a NullReferenceException :( Any suggestions?
Answer by skovacs1 · Nov 29, 2010 at 04:39 PM
EDIT: After re-reading the question and comments, I now believe that you were not properly passing the instances of the Item script to your array. Make sure to get them with GetComponent and that they actually have the script attached.
EDIT 2: As it seems the place wherein you are incorrectly passing the items to your inventory is in the collision code that you failed to provide, I will provide how that code and setup looks like for a working setup that I tested:
Item.js (attached to some object(s) in the scene)
var itemName : String;
function OnCollisionEnter(collision : Collision) { var script : Inventory = collision.gameObject.GetComponent(Inventory); if(script) script.AddItem(gameObject); else Debug.LogError(collision.gameObject.name + " has no inventory."); }
Inventory.js (attached to some other object(s) in the scene)
var size : int = 16; var items : Item[];
function Start() { items = new Item[size]; }
function OnGUI () { for(var i : int = 0; i < items.length; i++) { var item : Item = items[i]; if(item != null) GUI.Label(Rect(30, 30 * i, 120,30), item.itemName); } }
function AddItem(obj : GameObject) { if(obj == null) { Debug.LogError("Tried to add an invalid Item"); return; } var item : Item = obj.GetComponent(Item); if(item == null) { Debug.LogError("Tried to add an invalid Item"); return; } for(var i : int = 0; i < items.length; i++) { if(items[i] == null) { items[i] = item; Debug.Log("Added " + item.itemName); return; } } Debug.LogWarning("Inventory full."); }
Small note: Awake is only called once before Start - It doesn't get called when the script is enabled after being disabled (Unlike OnEnable)
Fair enough. I mistakenly thought it had to do with collisions and sleep. I will revise the answer.
I'm sorry, but that's not correct. In Derek's code, "currentItem" is cast as Item because of type inference. In loops, "i" is cast as an int because of type inference. Explicitly adding the type will do nothing as far as the compiled code goes; it's exactly the same. This has nothing to do with strict/dynamic typing, which is a different matter entirely.
One thing I noticed that you are doing differently is defining Item as a class inside Item.js... I was under the impression that because all scripts are technically classes in Unity, that I didn't need to do that (for instance, in my Item.js script itemName is just a public var). Is that my problem?
Also, in your example with class Item being defined in Item.js, if I wanted to have Item.js on an object in my scene, and be able to edit its itemName from the inspector, how would I go about doing that?
Your answer
Follow this Question
Related Questions
Checking if a position is occupied in 2D? 1 Answer
Getting information from an array 1 Answer
Ways to optimize this code? iterate through inventory 0 Answers
How to iterate through array? 1 Answer