Best way to reference a class within itself?

I have a class “Item”, which contains the data of the item, such as its name, icon, description, cost, etc. But I also want some items to require having other item(s) in order to be purchasable. What would be the best way to do that?
I can think of few ways:

  1. Add a field “id” to the items, and give a unique ID to each item (manually), and also add an int array “requirements”, which would hold all of the ids of the required items.
  2. Create another class “Requirements”, which would have 2 variables: Item item and Item[ ] requirements and when I am trying to purchase an item - I’ll do the check through THIS class instead.
  3. Instead of using item ID, or the class “Item” itself, I can instead use the items’ name in the requirements instead. So I’ll add a string[ ] requirements into the class, and manually fill the names of the required items. (And it will not work properly if I spell the name differently (like using different capitalization of the letters, or if I typo))

I tried to add “public Item[ ] requirements” to the Item class itself, but there were 2 problems with this:

  • Unity started giving me (yellow) warnings about a cycle within my class.
  • the requirements weren’t acting as a reference to the items, but rather as regular items instead.

I also tried using an array of pointers, but I got some errors within Visual Studio: “Cannot take the address of, get the size of, or declare a pointer to a managed type (‘Item’)”, as well as a warning for using an unsafe code.

How about you share us your code so far?

Well, technically I could, but I’m not sure how it will help, as I backed away from the idea of putting an Item[ ] into my Item class. And I haven’t exactly implemented the “check requirements” part yet, since how I would do that would entirely depend on the answer/s I get in this thread. But what I want to do, can be represented with the most generic class:

public class ItemsList : MonoBehaviour
{
    public Item[] item;
}

[System.Serializable]
public class Item
{
    // variables
    public Item[] requirements //Can't use this as a reference, unless I set it up into the Start or Awake methods, but Unity is still warning me about cycles in my script.
}

I set up the variables into the Unity Editor, via the UI.

I actually had another idea after going to sleep:

  • I could use the indexes of the array as an ID, but the drawback with this would be that again, I’ll have to manually set them, and if I displace the items, then I’d also need to change the requirement IDs as well, which could become overwhelming, if I have a lot of items.

You could make the ItemsList its own class to be the item requirements

public class ItemsList{
    public Item[] items;
}
public class Item{
    public ItemsList requirements;
}

and have another class to represent the ItemsList in monobehaviour

public class ItemsListMono: Monobehaviour{
    public ItemsList itemslist;
}

I am not exactly sure that I follow what you’re trying to do with this. It basically look like what I’ve tried, but instead of class A containing class A, you have class A containing class B and class B containing class A.
I suspect that what I am trying to do could be done like so:

public class ItemsList : MonoBehaviour
{
    public static Item[] item;

    void Awake()
    {
        item = GetComponents<Item>();
    }
}
public class Item : MonoBehaviour
{
    //variables
    public Requirements require;

    void Start()
    {
        this.enabled = false;
    }
}

[System.Serializable]
public class Requirements
{
    public Item[] items;
}

And I could add a separate script for each item, while the ItemsList would combine them into the array.

Or I could use the trick(s) I was using back when I was working on a Warcraft 3 map(s) and give intuitive IDs to the items. Like “Light Boots of Speed” could be represented with the ID ‘LBoS’ :stuck_out_tongue: (although I’m not sure if this will work right off the bat in C# or I’d need to make a “decoding” method first)

Okay, what I thought will work in the previous comment does indeed seem to work :slight_smile:
Making Item a MonoBehaviour and adding a different script for each item did resolve my problem. I am curious tho how efficient this is :stuck_out_tongue: