Hello
I have a question, on my inventory script, I have “currentSlot” which refers to another script, “SlotSystem”, in this script “SlotSystem”, I call a variable of type ItemData, which is another script creating item instances, as on the screen below. On my inventory script, I empty a variable named item present on my ItemData script, I empty this variable by doing: currentSlot.item = null;
but when I run the code, unity informs me of an error: NullReferenceExeption: object reference not set to an instance of an object Inventory.RefreshContent() (at Assets/Scripts/Inventory.cs:156)
Can someone help me, please.
Thanks you
Error :
Script Inventory :
using System.Collections.Generic;
using UnityEngine;
using System.Linq;
public class Inventory : MonoBehaviour
{
[Header("OTHER SCRIPTS REFERENCES")]
[SerializeField]
private Equipment equipment;
[SerializeField]
private ItemActionsSystem itemActionsSystem;
[SerializeField]
private CraftingSystem craftingSystem;
[SerializeField]
private BuildSystem buildSystem;
[Header("INVENTORY SYSTEM VARIABLES")]
[SerializeField]
private List<ItemInInventory> content = new List<ItemInInventory>();
[SerializeField]
private GameObject inventoryPanel;
[SerializeField]
private Transform inventorySlotsParent;
[SerializeField]
private KeyCode inventoryInput;
[SerializeField]
private SlotSystem slotSystem;
public Sprite emptySlotVisual;
public static Inventory instance;
const int InventorySize = 35;
private bool isOpen = false;
private void Awake()
{
instance = this;
}
private void Start()
{
RefreshContent();
CloseInventory();
}
private void Update()
{
if (Input.GetKeyDown(inventoryInput))
{
if (isOpen)
{
CloseInventory();
}
else
{
OpenInventory();
}
}
}
public void AddItem(ItemData item)
{
ItemInInventory[] itemInInventory = content.Where(elem => elem.itemData == item).ToArray();
bool itemAdded = false;
if (itemInInventory.Length > 0 && item.stackable)
{
for (int i = 0; i < itemInInventory.Length; i++)
{
if (itemInInventory[i].count < item.maxStack)
{
itemAdded = true;
itemInInventory[i].count++;
break;
}
}
if (!itemAdded)
{
content.Add(
new ItemInInventory
{
itemData = item,
count = 1
}
);
}
}
else
{
content.Add(
new ItemInInventory
{
itemData = item,
count = 1
}
);
}
RefreshContent();
}
public void RemoveItem(ItemData item)
{
ItemInInventory itemInInventory = content.Where(elem => elem.itemData == item).FirstOrDefault();
if (itemInInventory != null && itemInInventory.count > 1)
{
itemInInventory.count--;
}
else
{
content.Remove(itemInInventory);
}
RefreshContent();
}
public List<ItemInInventory> GetContent()
{
return content;
}
private void OpenInventory()
{
inventoryPanel.SetActive(true);
isOpen = true;
}
public void CloseInventory()
{
inventoryPanel.SetActive(false);
itemActionsSystem.actionPanel.SetActive(false);
TooltipSystem.instance.Hide();
isOpen = false;
}
public void RefreshContent()
{
// On vide tous les slots / visuels
for (int i = 0; i < inventorySlotsParent.childCount; i++)
{
SlotSystem currentSlot = inventorySlotsParent.GetChild(i).GetComponent<SlotSystem>();
currentSlot.item = null;
currentSlot.itemsVisual.sprite = emptySlotVisual;
currentSlot.countText.enabled = false;
}
// On peuple le visuel des slots selon le contenu réel de l'inventaire
for (int i = 0; i < content.Count; i++)
{
SlotSystem currentSlot = inventorySlotsParent.GetChild(i).GetComponent<SlotSystem>();
currentSlot.item = content[i].itemData;
currentSlot.itemsVisual.sprite = content[i].itemData.visual;
if (currentSlot.item.stackable)
{
currentSlot.countText.enabled = true;
currentSlot.countText.text = content[i].count.ToString();
}
}
equipment.UpdateEquipmentDesequipButtons();
craftingSystem.UpdateDisplayedRecipes();
buildSystem.UpdateDisplayedCosts();
}
public bool IsFull()
{
return InventorySize == content.Count;
}
public void LoadData(List<ItemInInventory> savedData)
{
content = savedData;
RefreshContent();
}
public void ClearContent()
{
content.Clear();
}
}
[System.Serializable]
public class ItemInInventory
{
public ItemData itemData;
public int count;
}
Script ItemData :
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//Creer un menu dans asset pour creer un scriptableObject
[CreateAssetMenu(fileName = "Item", menuName = "Items/New item")]
public class ItemData : ScriptableObject
{
[Header("Data")]
public string itemName;
public Sprite visual;
public GameObject prefab;
public string description;
public bool stackable;
public int maxStack;
[Header("Effects")]
public float healthEffect;
public float hungerEffect;
public float thirstEffect;
[Header("Armor Stats")]
public float armorPoints;
[Header("Attack Stats")]
public float attackPoints;
[Header("Types")]
public ItemType itemType;
public EquipementType equipementType;
}
//Enum pour créer les type d'item
public enum ItemType
{
Ressource,
Equipement,
Consumable
}
//Enum pour créer les types d'équipement
public enum EquipementType
{
Head,
Chest,
Hands,
Legs,
Feet,
Weapon
}
Script SlotSystem :
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
public class SlotSystem : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler
{
public ItemData item;
public Image itemsVisual;
public Text countText;
[SerializeField]
private ItemActionsSystem itemActionsSystem;
//Quand la souris est sur un Slot
public void OnPointerEnter(PointerEventData enventData)
{
//Si l'objet et différent de null, on montre le menu Tooltip et on écrit la description et le nom de l'item choisit
if (item != null)
{
TooltipSystem.instance.Show(item.description, item.name);
}
}
//Quand la souris n'est plus sur un Slot
public void OnPointerExit(PointerEventData enventData)
{
//Cache le menu ToolType
TooltipSystem.instance.Hide();
}
//Quand on clique sur un Slot
public void ClickOnSlot()
{
itemActionsSystem.OpenActionPanel(item, transform.position);
}
}