Issue accessing objects in List<T>.

I have an item inheritance chain that goes something like.

Item → Food → CanOfBeans.

//item.js

#pragma strict

public class Item {
	var itemName : String;
	var invCategory : String;
	var itemWeight: float;
}
public class Food extends Item {
	var numUses: int;
	var recoverHunger : int;
}
public class Weapon extends Item {
	var ammo : int;
}
/*************************************************FOODS*************************************************/

public class CanOfBeans extends Food {
	var itemDurability : int;
}

/************************************************WEAPONS************************************************/

public class Beretta9mm extends Weapon {
	var weaponDurability : int;
	var weaponDamage : int;
}

Each item has their own Script attached to them. Items have an obj of their type attached to them. I call function AddItem and Add them to the list.

//ItemManager.js
#pragma strict

import System.Collections.Generic;

public var weight : float;
public var maxWeight : float;

var invList : List.<Item> = new List.<Item>();

function Update () {
    if (Input.GetKeyDown ("f")) {
        var ray : Ray = Camera.main.ScreenPointToRay (Input.mousePosition);
        var hit : RaycastHit;
        
        if (Physics.Raycast(ray, hit)) {
            if (hit.collider.tag == "Item"){ 
            	hit.collider.gameObject.SendMessage("AddItem"); 
            }
        }
    }
}
//CanOfBeansAtt.js
//Attached to Prefab "Can of Beans"
#pragma strict

public var itemObj : CanOfBeans;

public function AddItem() {	
	var x = GameObject.FindGameObjectWithTag("Manager").gameObject.GetComponent(ItemManager);	
	if(x.weight + itemObj.itemWeight <= x.maxWeight) {
		x.weight += itemObj.itemWeight;			
		x.invList.Add(itemObj);
		Destroy(gameObject);
	}
}

I have a lot of functionality added into this inventory, and it works in general, but inventory management is a pain in the rear because my inventory List is of type Item. This means that I cannot access all of the data for each item in my List.

I must first create a variable of the same type ie

var temp : CanOfBeans;

and then assign temp to invList*.*
```
*//Code to use a Can of Beans.
var temp : CanOfBeans = gameObject.GetComponent(ItemManager).invList[target];
transform.parent.gameObject.GetComponent(PlayerAttributes).hunger += temp.recoverHunger;
gameObject.GetComponent(ItemManager).invList.RemoveAt(target);
temp.numUses -= 1;
if(temp.numUses > 0)
gameObject.GetComponent(ItemManager).invList.Add(temp);
itemUseOn = false;

//Instead of assigning it to temp, I would rather be able to access it directly through
//gameObject.GetComponent(ItemManager).invList[target].recoverHunger;*
```
I realize that this is because the items in invList are type Item but I do not know how to resolve this. Item management is going to get more intense going forward and I need to resolve this before it gets too messy.
Thanks.

One caveat that might be bad news for you: last I knew, Unity serialization isn’t polymorphic. Given a List, Unity will serialize only the fields which belong to the Item class. At runtime, the list could certainly contain Foods, Weapons, and more… but as far as serialization is concerned, they’re all just Items.

If you’re only using the list at runtime, you can always check and cast types, using “is” and “as” operators (or explicit casts), to get access to whatever you need. Ultimately, this sort of system can be pretty hard to get together just right.

Is there a specific problem you’re having, or are you more looking for general advice?

I wonder what my options are mostly. There will be a large amount of items in this game ranging from junk like forks/spoons to weapons. I estimate that there might be 200+ items.

I really don’t want to have to create separate cases for every item type such as

var x : CanOfBeans
var y : Ammo9mm
var z : Fork

etc…it could get really out of hand.

One option that comes to mind is that perhaps I stop my inheritance chain at the sub level before individual item depth. So in this way, a CanOfBeans would simply be of type Food instead of type CanOfBeans.

It might be worth defining your classes as monobehaviours or even scriptable objects since both of these support polymorphic serialization:

public class Item extends MonoBehaviour {
    // Can just use MonoBehaviour.name :)
    var invCategory : String;
    var itemWeight : float;
}

public class Food extends Item {
    var numUses: int;
    var recoverHunger : int;
}

// or...

public class Item extends ScriptableObject {
    // Can just use ScriptableObject.name :)
    var invCategory : String;
    var itemWeight : float;
}

public class Food extends Item {
    var numUses: int;
    var recoverHunger : int;
}

I would just make my item class completely inspecific, with rules in your code that understands what each item is and how to break it down into a specific class. Not as awesome as de-serializing the entire file into classes automagically.

public class Item
{
public string Name;
public float Weight;
public int NumUses;
public ItemType Type;
public object Parameter1;
public object Parameter2;
public object Parameter3;
public object Parameter4;

}

I’d go with numberkruncher’s approach and use MonoBehaviours to describe object ‘traits’ (one component for ‘edible’, one component for ‘collectible’, etc), then make a prefab for each object.

Ill give it a shot and see what happens. thanks