Object Null Reference C# - Not Displaying Items in Array!! Help Appreciated...

Hi guys,

Trying to follow this tutorial from burgzergarcade: https://www.youtube.com/watch?v=Wg0ncI2j5OA
in which it generates items in my loot source; and thus I’m able to loot them :slight_smile: at the moment its nothing special, but its no longer generating any items in the chest, leaving it completely empty and giving me an object null reference from line 59, of the Scavenge GUI…

“NullReferenceException: Object reference not set to an instance of an object
Scavenge_GUI.ScavengeWindow (Int32 id) (at Assets/_Scripts/UnfinishedScripts/Scavenge_GUI.cs:59)”

Scavenge:

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

[RequireComponent(typeof(BoxCollider))]
[RequireComponent(typeof(AudioSource))]

public class Scavenge : MonoBehaviour {

	public enum State
	{
		Open,
		Close,
		Inbetween
	}
	
	public AudioClip OpenSound; // Sound played when Loot Source is Opened
	public AudioClip CloseSound; // Sound played when Loot Source is Closed
	public GameObject ParticleEffects; // The Particle effect displayed upon opening
	public State LootState;	// The current State
	public float MaxDistanceToLoot = 2; // The Max Distance a player can loot from
	public bool StatusChecker; // Checks the current Status of the chest depending on player input, gets component from the GUI Script
	public GameObject AreaRestrictor1;
	public GameObject AreaRestrictor2;
	public GameObject AreaRestrictor3;
	public GameObject AreaRestrictor4;
	
	private GameObject PlayerCheck;
	public List<Item> Loot = new List<Item>();
	
	void Start () 
	{
		LootState = Scavenge.State.Close;
		ParticleEffects.active = false;
		
		animation["Open"].speed = 4f; // multiplies the open speed here for the chest.
		animation["Close"].speed = 4f; // multiplies the close speed here for the chest. edit at some point
		
		AreaRestrictor1.collider.enabled = false;
		AreaRestrictor2.collider.enabled = false;
		AreaRestrictor3.collider.enabled = false;
		AreaRestrictor4.collider.enabled = false;
	}
	
	void Update () 
	{

		GameObject PlayerCheck = GameObject.FindGameObjectWithTag("Player");
		
		if (Vector3.Distance(transform.position, PlayerCheck.transform.position) > MaxDistanceToLoot)
		return;
		
		if (Input.GetButton("Cancel Button"))
		switch(LootState)
		{
		case State.Open:
			AreaRestrictor1.collider.enabled = false;
			AreaRestrictor2.collider.enabled = false;
			AreaRestrictor3.collider.enabled = false;
			AreaRestrictor4.collider.enabled = false;
			LootState = Scavenge.State.Inbetween;
			StartCoroutine("Close");
			StatusChecker = false;
			
			break;
		}
		
		if (Input.GetButton("Interact Button"))
		switch(LootState)
		{
		case State.Close:
			AreaRestrictor1.collider.enabled = true;
			AreaRestrictor2.collider.enabled = true;
			AreaRestrictor3.collider.enabled = true;
			AreaRestrictor4.collider.enabled = true;
			LootState = Scavenge.State.Inbetween;
			StartCoroutine("Open");
			StatusChecker = true;	
			break;	
		}
	}
	private IEnumerator Open()
	{	
	//	Messenger<int, GameObject>.Broadcast("PopulateLootSource", 5, gameObject, MessengerMode.DONT_REQUIRE_LISTENER);
		PopulateLootSource(5);
		Messenger.Broadcast("DisplayLoot");
		animation.Play("Open");
		ParticleEffects.active = true;
		audio.PlayOneShot(OpenSound);
		
		yield return new WaitForSeconds(animation["Open"].length / 4);
	
		LootState = Scavenge.State.Open;
	}
	
		private void PopulateLootSource(int x)
	{	
		for(int cnt = 0; cnt < x; cnt++)
		{
			Loot.Add(new Item());
			Loot[cnt].Name = "I:" + Random.Range(0, 100);
		}
	}
	
	
	private IEnumerator Close()
	{	

		animation.Play("Close");
		ParticleEffects.active = false;
		yield return new WaitForSeconds(animation["Close"].length / 4);
		
		audio.PlayOneShot(CloseSound);
		LootState = Scavenge.State.Close;
	}	
	
	public bool StateStatus()
	{
		if(StatusChecker)
			return true;
		else
			return false;
	
	}
}

Scavenge GUI

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class Scavenge_GUI : MonoBehaviour {
	
	private const int Scavenge_Window_ID = 0;
	private Rect Scavenge_Window_Rect = new Rect(0,0,0,0);
	private List <Item> Loot_Items;
	private Vector2 Scavenge_Window_Slider = Vector2.zero;
	public static Scavenge ScavengeSource;
	
	public float Button_Width = 40;
	public float Button_Height = 40;
	public float GUI_Offset = 10;
	public float Scavenge_Window_Height = 90;
	public bool Display_Scavenge_Window = false;
	
	
	void Start () 
	{
		Loot_Items = new List <Item>();
		Display_Scavenge_Window = false;
	}
	
	private void OnEnable()
	{
		Messenger.AddListener("DisplayLoot", DisplayLoot);
		Messenger.AddListener("Close Loot Source", ClearWindow );
	}
	
	private void OnDisable()
	{
		Messenger.RemoveListener("DisplayLoot", DisplayLoot);
		Messenger.RemoveListener("Close Loot Source", ClearWindow);
	}
	
	void Update () 
	{
		if (Input.GetButton("Cancel Button"))
			ClearWindow();
		else 
			if (ScavengeSource == null)
			return;
	}
	
	void OnGUI()
	{
		if (Display_Scavenge_Window)
		Scavenge_Window_Rect = GUI.Window(Scavenge_Window_ID, new Rect(GUI_Offset, Screen.height - (GUI_Offset + Scavenge_Window_Height), 
		Screen.width - (GUI_Offset * 2), Scavenge_Window_Height), ScavengeWindow, "Scavenge");
	}
	
	private void ScavengeWindow(int id)
	{
		Scavenge_Window_Slider = GUI.BeginScrollView(new Rect(GUI_Offset*.5f, 15, Scavenge_Window_Rect.width - 10, 70), Scavenge_Window_Slider,
		new Rect(0, 0, (Loot_Items.Count * Button_Width) + GUI_Offset, Button_Height + GUI_Offset));
		
		for(int cnt = 0; cnt < ScavengeSource.Loot.Count; cnt ++)
		{
			GUI.Button(new Rect(5 + Button_Width * cnt, GUI_Offset, Button_Width, Button_Height), ScavengeSource.Loot[cnt].Name);
		}
		
		GUI.EndScrollView();
	}
	
	private void DisplayLoot()
	{
		Display_Scavenge_Window = true;
	}
	
	private void ClearWindow()
	{
		Loot_Items.Clear();
		
		ScavengeSource = null;
		Display_Scavenge_Window = false;
	}
}

Where do you instantiate ScavengeSource? You have it declared as static in the Scavenge_GUI, are you linking the object in Unity’s Inspector? The Loot public field in the Scavenge has at the very least an instantiated List of element count zero, so that shouldn’t be causing the null reference, but ScavengeSource seems to be null. Make sure that if the video instructed you to link in the inspector you do, or instantiate the object in the GUI class.

Sorry Im kinda new to scripting.

So basically should i also do a Public Game Object; in which i drag the “ScavengeSource” to it in the Unity Inspector and ensure its name is “ScavengeSource”?

I’m not say that at all, i didn’t watch the video, the fact that i don’t know if you linked up something from your scene to your code in the inspector is just an observation. The fact is, it appears that ScavengeSource doesn’t get instantiated or created, this leaves you with the Null reference error. I can determine it isn’t the List since it is clearly instantiated(created) inside the Scavenge script.

Im guessing I was missing this?

Scavenge_GUI.source = this;

Also,

any idea why my items are continuing to count up? on every iteration it doubles its current count.

Looksl ike ScavengeSource is null because it is never being set.

One option is to put both components on an object and in ScavengeGUI.Start do a “ScavengeSource = gameObject.GetComponent(“Scavenge”)”. Other option include adding both components to an object and using the Unity Editor GUI to drag/drop Scavenge over to ScavengeSource.

Every time open is called this happens:

    private void PopulateLootSource(int x)
    {   
        for(int cnt = 0; cnt < x; cnt++)
        {
            Loot.Add(new Item());
            Loot[cnt].Name = "I:" + Random.Range(0, 100);
        }
    }

Sorted it,

cheers

Landern:)