2

I've seen this question several times on the site, however most of the solutions seem to indicate that I should just make it an instance variable rather than a static one. However, the whole point of the Singleton pattern is this static object that's consistently referred to. Here are the links I have looked at:

Member cannot be accessed with an instance reference; qualify it with a type name

Member '<method>' cannot be accessed with an instance reference

This last link led me to the following:

What does the 'static' keyword do in a class?

And I feel I do understand this. The point of the Singleton is that all classes share this one instance so it feels perfect? I don't see the issue? It should be static according to Singleton conventions and frankly logic.

I'm in unity and am trying to make an inventory system for a game some fellow students and I are trying to make. I have the InventoryUI set up, however I would like to build a static inventory that is ever-present in the game. The InventoryUI will draw the necessary data from this Singleton class.

In other words, the PlayerInventory will act as the backend for the InventoryUI. The PlayerInventory will be a Singleton and the InventoryUI will draw the necessary data from PlayerInventory

Here is the relevant code for my Singleton class:

public class PlayerInventory : MonoBehaviour
{
    private static PlayerInventory instance;

    private PlayerInventory() { }

    public static PlayerInventory getInstance()
    {
        if (instance == null)
            return instance = new PlayerInventory();

        return instance;
    }
}

Here is the relevant code for my InventoryUI class:

public class PlayerInventoryUI : MonoBehaviour
{
    //Inventory Instance
    static PlayerInventory inventory;

    void Start()
    {
        inventory = inventory.getInstance(); 
        //cannot be accessed with an instance reference Error occurs here.
    }
}

If possible, could someone explain to me why this error occurs as well as a possible solution.

James9oo0
  • 159
  • 12

2 Answers2

2

That static method is in the class, not in an instance. So change your code in InventoryUI to this:

public class PlayerInventoryUI : MonoBehaviour
{
    //Inventory Instance
    static PlayerInventory inventory;

    void Start()
    {
        inventory = PlayerInventory.getInstance(); 
        //works because static methods are called from the class
    }
}

I use Singletons with Unity a lot, have shared my pattern in a Quora answer: https://qr.ae/TSqaWt

Oh and if your Inventory is not in some GameObject Script component, it does not need to inherit from MonoBehaviour. Is better to use just a plain C# class if you don't need to use MonoBehaviour things like having Unity call Update on it.

If you wan't to have it as a script component, which can be nice to have it show in the inspector etc, then you should not 'new' it yourself but let Unity create it and assign the instance to the static reference when that happens. Is good to do that in Awake() so the singleton is already there when other scripts do Start()

antont
  • 2,676
  • 1
  • 19
  • 21
0

Try the following instead: inventory = PlayerInventory.getInstance();

You are attempting to call a static method on an (uninitialized) instance variable which is not allowed. Static methods must be qualified with the type (class) name, as the error suggests.

You have defined a static method inside a non static class, and although it's perfectly legal, the two should be thought of as seperate entities. Static methods only have access to static fields of the class, they cannot access any instance variables. The memory of static data members is allocated individually without any relation with the object.

Look at String.Parse() as an example, you wouldn't write mystring.Parse(), but instead you use the static method Parse of the String class which is always available and does not require a new string instance to use.

Hope this helps, if any further questions I will try to explain better.

Jeff Barnard
  • 104
  • 5