I have a bit of code that allows a player to take a pickup object into their inventory, however i cant get the start function to work, it keeps turning up null. The null reference is to the Inventory variable which isnt being set upon start here's the code Code (CSharp): using System.Collections; using System.Collections.Generic; using UnityEngine; public class Pickup : MonoBehaviour { public Inventory inventory; public GameObject itemButton; public void Start() { inventory = GameObject.FindGameObjectWithTag("Player").GetComponent<Inventory>(); } private void OnTriggerEnter2D(Collider2D other) { if (other.name == "Player") { // spawn the sun button at the first available inventory slot ! for (int i = 0; i < inventory.slots.Length; i++) { if (inventory.isFull[i] == false) { // check whether the slot is EMPTY inventory.isFull[i] = true; // makes sure that the slot is now considered FULL Instantiate(itemButton, inventory.slots[i].transform, false); // spawn the button so that the player can interact with it Destroy(gameObject); break; } } } } }
Code (CSharp): GetComponent<Inventory>(); This code will return null if the Pickup script and the Inventory script are not on the same GameObject. If they're not on the same GameObject, this is not the right way to assign your variable.
sorry i realized this after posting, i changed it but it still wont load the Inventory script on start Code (CSharp): private void Start() { inventory = GameObject.FindGameObjectWithTag("Player").GetComponent<Inventory>(); }
I fixed it by changing FindGameObjectWithTag to Gameobject.Find.("Player").GetComponent<Inventory>();
I highly recommend avoid using strings, especially names, it can easily cause mistakes if you made typo for example. Make script called Player and search for player with FindObjectOfType<Player>(), in that case method will return Player script instead of GameObject and compiler will help dealing with typos. It will be ten times more reliable. You can also catch some errors on start with thing like that: Code (CSharp): var player = FindObjectOfType<Player>(); if (player != null && player.TryGetComponent(out Inventory inv)) { inventory = inv; } else { Debug.LogError("There is no player or it doesn't have an inventory)"; }
Just drag the Player gameobject with the Inventory script into the Inventory slot (because it's public), then you can access everything in the script right away. No Find or GetComponent is needed, dragging it in sets the reference. Only do that if it's private.
I thought thatd be a good fix too, however when instantiating the items back into the world from the inventory they wont be set to the players inventory and wont be picked up, it wasnt picking up on the player tag for some reason and changing it to Find fixed this issue