- Home /
One component in Array which is a class resets itself to null.
I don't even know how to formulate a question since I have 0 idea why this error is occurring. My observation, after 5 quadrillion Debug.Log statements, is that somewhere along storing the class array which includes class, the class value becomes null. I have checked this through confirming whether or not the values actually change. It's better explained through code.
Inventory.cs: handles inventory storage as well as GUI display.
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.UI;
public class Inventory : MonoBehaviour {
public ItemClass holdingNow;
inventoryItems[] inventoryStuff = new inventoryItems[5];
public GameObject[] itemIconGUI = new GameObject[5];
public GameObject[] itemNumberGUI = new GameObject[5];
// Use this for initialization
void Start () {
Debug.Log ("start");
inventoryStuff [0] = new inventoryItems (null, "", 0);
inventoryStuff [1] = new inventoryItems (null, "", 0);
inventoryStuff [2] = new inventoryItems (null, "", 0);
inventoryStuff [3] = new inventoryItems (null, "", 0);
inventoryStuff [4] = new inventoryItems (null, "", 0);
}
// Update is called once per frame
void Update () {
//update gui display
for (int i = 0; i < 5; i++) {
Debug.Log ("updating GUI");
itemIconGUI [i].GetComponent<Image> ().sprite = Sprite.Create (inventoryStuff [i].iClass.itemTexture, new Rect (0, 0, 30, 30), new Vector2 (0.5f, 0.5f));
itemNumberGUI [i].GetComponent<Text> ().text = inventoryStuff [i].numberOfItem.ToString ();
}
}
public void AddItem (ItemClass itemClass) {
for (int i = 0; i <= 4; i++) {
Debug.Log (inventoryStuff [i].iClass + ", " + inventoryStuff [i].item + ", " + inventoryStuff [i].numberOfItem);
}
//already exists and stackable
for (int i = 0; i <= 4; i++) {
if (inventoryStuff [i].item == itemClass.itemName) {
Debug.Log (itemClass);
if (inventoryStuff [i].numberOfItem < itemClass.maxStack) {
inventoryStuff [i].iClass = itemClass;
inventoryStuff [i].numberOfItem += 1;
Debug.Log ((ItemClass)inventoryStuff [i].iClass);
return;
}
}
}
int firstEmptySlot = emptySlot ();
if (firstEmptySlot >= 0) {
inventoryStuff [firstEmptySlot].iClass = (ItemClass)itemClass;
inventoryStuff [firstEmptySlot].item = itemClass.itemName;
inventoryStuff [firstEmptySlot].numberOfItem = 1;
return;
}
if (firstEmptySlot < 0) {
Debug.Log ("inventory full");
return;
}
}
int emptySlot() {
for (int i = 0; i <= 4; i++) {
if (inventoryStuff [i].item == "") {
return i;
}
}
return -1;
}
public class inventoryItems {
public ItemClass iClass;
public string item;
public int numberOfItem;
public inventoryItems(ItemClass cla, string ite, int num) {
iClass = cla;
item = ite;
numberOfItem = num;
}
}
}
ItemInteraction.cs: handles interactions between player and item tagged objects.
using UnityEngine;
using System.Collections;
public class ItemInteraction : MonoBehaviour {
private Vector3 position;
public GameObject inventoryManager;
void Start() {
position = new Vector3(Screen.width/2, Screen.height/2);
}
void Update () {
if(Input.GetKeyDown(KeyCode.E) && !UnityEngine.EventSystems.EventSystem.current.IsPointerOverGameObject()) {
Collect ();
}
}
void Collect () {
Ray interactRay = Camera.main.ScreenPointToRay (position);
RaycastHit interactionInfo;
if (Physics.Raycast (interactRay, out interactionInfo, 100)) {
GameObject collectableObject = interactionInfo.collider.gameObject;
if (collectableObject.tag == "item") {
Destroy (collectableObject);
inventoryManager.GetComponent<Inventory> ().AddItem (collectableObject.GetComponent<ItemClass> ());
Debug.Log (collectableObject.GetComponent<ItemClass> ());
}
}
}
}
ItemClass.cs: base class for items.
using UnityEngine;
using System.Collections;
public class ItemClass : MonoBehaviour {
public string itemName = "item";
public int maxStack = 30;
public Texture2D itemTexture;
public virtual void Use() {
}
public virtual void Trash() {
}
}
I suspect that the storing of the data type ItemClass is where everything is going terribly wrong, though I don't see why because the class array's class specifies the ItemClass.
Answer by Bunny83 · Apr 08, 2017 at 01:10 AM
Well, your ItemClass is a component. Components can only exist on gameobjects. Your problem is that you destroy the gameobject that contains the ItemClass component which you add into your list. When the gameobject get destroyed all components on that gameobject are destroyed as well. References to destroyed components become "fake-null" objects.
How would I address this issue then? Because I think its important for my script to have ItemClass as a part of the array.
Is there a way to store it without the script needing to be attached to a gameobject?
No, it's not. Your concept simply doesn't work that way. You basically have two options:
Use an item class that is not a component. Either use a ScriptableObject or a normal class. That instance can be referenced by a component script on the phyical item in the scene.
If you want to use the item as component you must not destroy the object. You can deactivate the object or just disable certain components and maybe parent the object to a container object on your player. That way the object is no longer visible but still exists .