Help with theory on scripting my crafting system.

It was recomended I move this here from Unity Answers. Thanks in advance for any help you can provide!

Hi Unity,

I am about to start creating my own crafting system and I am looking for some help on my theory before I jump in head first.

What I have today is a basic inventory system based around an Item script which defines what an item is and gives it things like an icon, tooltip, and other properties.

I have the ability to collect items in the game and add them to my inventory.

Now what I am looking to do is create a GUI window that allows you to put items in it and checks to see if you have certain items, if you have those items, in a gui box to the right a craftable item will show up.

So here is how I plan to implement this - and I am trying to find a better way to set up the recipe system:

Using OnMouseDown to detect if player has clicked on crafting table, if so GUI window pops up.

Use a for Loop to loop through current items in the players inventory.

(Now here is where I need some help to figure the best way to do this)

My original thought, which I think is probably terrible, is have a seperate set of variables in my crafting class, basically one variable for every item in the game.

As I loop through the player inventory, I can check if item.name == whateverItem. If it is, I increase a counter for that item.

Then after the for loop I can check the count for all my variables and if I have one of each of the items needed for itemX, then that icon shows up.

Something maybe like this?

private string basicWoodName = "basicWood"
    private int basicWoodCount= 0;
    
    private string basicStoneName = "basicStone"
    private int basicStoneCount = 0;
    
    for(int cnt; cnt < itemScript.playerInventory.count; cnt++)
    {
      if(itemScript.playerInventory[cnt].name == basicWoodName)
      {
      basicWoodCount++;
      }
    
        if(itemScript.playerInventory[cnt].name == basicStoneName )
      {
      basicStoneCount++;
      }
    
    
    }
    //I would need one of these for every item.. ouch
    
    //Then I would need recipe's - something like this maybe? (terrible I know)
    if(basicWoodCount == 6  basicStoneCount == 1)
    {
      //Show GUI Icon for a Sword
    }
    
    //I would need one of these for every possible combination.. Ouch

Of course I will need to add a lot more to this script but I am just trying to formulate the basic idea of how this is going to work.

Thoughts on a better way to do this before i start?

Thanks!

Uhm, how about having an array or list of all the craftable items, and then via. a loop, make it check if you have the necessary materials for the specific recipe.

That sounds better - can you give a noob a bit more detail? :slight_smile:

How would you compare the items in the list of craftable items, to the loop that goes through whats in my inventory?

Im a bit of a noob myself, but I can try :stuck_out_tongue:

I think you can put your current materials in your inventory in another list, with a loop, and then compare the materials list with the recipes list, and if there is a match, print it to a gui button, and if the gui button is clicked, make the item, and refresh the materials list, and compare the lists again.

Well one thing you could do is as Roi mention to store all possible items in an array or C# list.

A smart way to do this is to create a base class called something like Item. And then make all game items inherit from this class. Then an Item[ ] itemArray can hold all the different items.

Implement a check method that takes your inventory variables and check against the requirement of an item. Each new item class then defines the requirements. Then you only need to write the check once!

Furthermore you can hold all sword information and such in the sword class, and all spear information in the spear class.

If you need an example i can write one tomorrow quickly, just PM me or write in here.

Ya that would be awesome.

I understand how to create a list or array and put the items into it when they are clicked in my inventory - BUT what I cant figure out is the best way to then check and see what is in that list, and if its the ingredients to make something, then allow that item to be made.

So far the only way I can figure out how to do that is store the amount of what is in the list in some variables, and then check to see if those variables are equal to the ingredients of the item that would be made. But that seems messy and not the best way.

Actually for you to understand my approach and learn anything you need to understand inheritance and polymorphism. So start by googling that and you should be able to create the solution yourself.

If you get a grasp on that and it still bothers you then just PM me.

Are the crafted items also item classes?
If so you can simply add a function “Recipe” in all item classes, this function can take an item list and return either itself or a new instance of itself, or a bool, depending on design. Or it returns negative. This function could be static.
So when you have the inventory and are ready to check for crafting, you run all the items Recipie functions and see which ones returns valid.
For optimisation you probably want to do this check every time a new item is added or removed to the inventory instead of in the GUI function, and save the result in a class variable in maybe the crafting class named “CraftableItems” or something similar.

@ BFGames - I am fairly familiar with inheritance - somewhat with polymorphism but I will freshen up on it. If you want to post your idea though that would be more helpful and then I can research further to understand it. Thanks a bunch.

@Sirex - Yep they are - I have a base class Item and then inherited classes like Weapon, Armor, etc. So this function - it would take in my inventory list of items, and basically checks to see if they match the required list of “ingredients” for the recipe, and if not returns null, otherwise it returns either the receipe or a bool saying its true?

Maybe if you could provide just a bit more detail though. You are saying put one of these functions for each item class? I guess I am just not quite sure what I am checking with this function. When an instance of this object type is created for the inventory list, then you run this function. I get that - but what am I checking in this function exactly?

Edit - After some further research I think I could maybe use some code that compares two lists together. Currently looking more into this and will post back with more details.

Wouldn’t it be easier to have the player select a recipe then open a new window similar to your inventory with slots to place items… have the player drop in items and just check if the item added is valid for the selected recipe?

Thats not a bad idea - theoretically I could just completely remove even having to drop the items in at all and just have them select the recipe first which would eliminate having to check the items and compare them to the recipe. I might actually start looking at this method for now because I cant seem to figure out how to check my list of items versus several lists of recipes. I will post back with results either way.

You can check items in an array by name. :wink:

(eg)

if(myArray[indexNum].name==“someStringName”) {
// Let me know about it.
}

@Black Maintis - True, but the problem really isnt checking the items, its more checking to see if the items I have in a list<> of items matches the ingredients for the recipe I am trying to make.

IE: To make a sword requires 5 pieces of wood and 1 peice of stone. I need to check if I have those items in my inventory.