Access Array from static void (C#)

I am having trouble accessing my Transform from a static void within the same script.

Example:
using UnityEngine;
using System.Collections;
using UnityEngine.UI;

public class InventorySlots : MonoBehaviour {
	
	public Transform[] Slots;


	void Start(){
		Slots = gameObject.GetComponentsInChildren<Transform> ();
	}

	void Update () {
	foreach (Transform Slot in Slots) {
			if (!(Slot.name == "InventoryPanel")) {
				if (Slot.GetComponent<Image> ().sprite == null) {
					Slot.tag = "EmptySlot";
					//Slot.gameObject.SetActive (false);
				} else {
					Slot.tag = "FilledSlot";
					//Slot.gameObject.SetActive (true);
				}
			}
		}
	}

	public static void ChangeImage(GameObject ItemObject){
		foreach (Transform Slot in Slots) {
			if(Slot.GetComponent<Image>().sprite == null){
				Slot.GetComponent<Image>().sprite = Resources.Load ((ItemObject.GetComponent<UID>().UniqueIdentifier).ToString ())as Sprite;
			}
		}
	}
}

But I keep getting this compiler error:

InventorySlots.cs(29,44): error CS0120: An object reference is required to access non-static member `InventorySlots.Slots’

I was wondering whether or not someone could point me the correct to solve this problem.
And also if I change the Transform to be a static variable, the script that references the static void shows this error:

NullReferenceException: Object reference not set to an instance of an object
InventorySlots.ChangeImage (UnityEngine.GameObject ItemObject) (at Assets/_SCRIPTS/InventorySystem/InventorySlots.cs:30)
PickUpFood.Update () (at Assets/_SCRIPTS/_SurvivalMechanics/Food/PickUpFood.cs:20)

If you need anymore information just let me know.

This is because you misunderstand how static works. :slight_smile:

Ok, so you have a static function. What is a static function? It is a function that is independent of a generated object (simple explanation). As such, you call it by using the TYPE, not the variable.

MyType.StaticFunction()

not

MyType myobject = new MyType();
myobject.StaticFunction();

Now what does this mean for you? It means that when you try to reference Slots, which is non static, you are asking the static function to operate on an instance member. How does it know which Slots you want? If you generated 10 of these objects, the static function has no idea which one to use, as they could be different for each object.

So you make it static, and now it is common to all instances of this class. But your second error? Well, kinda need to see how you are calling this method. I tshould be called like so:

InventorySlots.ChangeImage();

but I bet you are doing GetComponent().ChangeImage(), which is incorrect. Why? Because that is an instance of the class, not the class type itself.

Think about other plaes in the engine that use static methods. Vector3.Distance() for instance. You don’t do “myVector.Distance()”; you do “Vector3.Distance()”.

You should read up a bit on static variables/classes in C#. This is unrelated to Unity really.

The idea of method belonging to object is deceitful. When you have 20 objects of a type, you do not have 20 times the method for each object in memory. That would be a waste of space.

Instead the compiler creates one version of the method in the static part of the memory and creates a reference (a variable with the address of the method) for each object.

So doing this:

 public void MyMethod(){}

means you have a reference (4 bytes only) containing the address where the method is stored.

Now how could the compiler be able to access the variables of a specific instance if that method is the same for all?

Well this is because the compiler adds a hidden parameter to your method:

 public void MyMethod(this TypeOfClass objRef){}

so when you do

 myObj.MeMythod();

compiler converts to

 TypeOfClass.MyMethod(myObj);

and that is how you get your access.

Static does pretty much the same except that the compiler does not add the hidden parameter. So the method is left alone in the static memory and hence can only access the static variables and methods.

So in order to access a non-static member within a static class, you need to pass it as a parameter explicitly

public static MyMethod(TypeHere myInstanceObject){}

this way, the myInstanceObject is refered within the static method, despite not being static as you provide the address while calling the method.

So in your case:

public static void ChangeImage(GameObject ItemObject, GameObject [] array){
     foreach (Transform Slot in array) {
         var image = Slot.GetComponent<Image>();
         if(image != null && image.sprite == null){ 
               image.sprite = Resources.Load ((ItemObject.GetComponent<UID>().UniqueIdentifier).ToString ())as Sprite;
         }
     }
 }