How to check if each element in a list has met a condidion?

Hello,
I have a problem. I am trying to make a building system, and i want to make it so you can only build something, if you have the resources for it. E.g you can build a house only if you have 10 copper and 10 iron. I have made a list with all the resources the player can obtain, and a list for all the resources the building requires. I have been trying for the past 3 days to make it so you can build the house when you have BOTH 10 copper and iron. Can you help me? Any kind of help is appreciated.
Code(So dumb for not doing it in the first place) :
The building script :

using UnityEngine;

public class BuildingScript : MonoBehaviour
{
	public GameObject item;
	Building thisBuilding;
	ResourcesSystem inv;
	public bool canBuild;

	private void Start()
	{
		inv = GameObject.FindObjectOfType<ResourcesSystem>();
	}

	private void Update()
	{
		Build();
	}

	void Build()
	{
		Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);

		RaycastHit hit;
		if (Input.GetMouseButton(0))
		{
			UpdateComponent();
			if (Physics.Raycast(ray, out hit))
			{
				if (hit.collider.tag == "Ground")
				{
					for (int i = 0; i < inv.resources.Length; i++)
					{
						if(inv.resources*.resource == thisBuilding.required.resource)*
  •  				{*
    

_ if(inv.resources*.amount >= thisBuilding.required.amount)_
_
{_
_
Vector3 itemPos = item.transform.position;*_

* itemPos.x = Mathf.Round(hit.point.x);*
* itemPos.y = Mathf.Round(hit.point.y) + (item.transform.localScale.y / 2 + .5f);*
* itemPos.z = Mathf.Round(hit.point.z);*

* item.transform.position = itemPos;*

* Instantiate(item);*
_ inv.resources*.amount -= thisBuilding.required.amount;
}
}
else*
* {
continue;
}
}
}
}
}
}*_

* void UpdateComponent()*
* {*
* thisBuilding = item.GetComponent();*
* }*
}
I made it so it only required one type of resource to build.
Resources System :
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ResourcesSystem : MonoBehaviour
{
* public ResourceItem[] resources;*
}
[System.Serializable]
public class ResourceItem
{
* public Resource resource;*
* public int amount;*
}
The single resource (I made it as a scriptable object, because i want to add more resources in the future)
:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[CreateAssetMenu(menuName = “Resource”, fileName = “New Resource” , order = 1)]
public class Resource : ScriptableObject
{
* public string Name;*
}
The script in each building:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Building : MonoBehaviour
{
* public GameObject building;*
* public int cost;*
* public ResourceItem required;*
}

Thats all there is. If you cant figure out how to make it so it requires multiple resources to build, i will just rewrite it differently.

You could setup an XML structure file for all your recipes like

<house id="1">
<copper>10</copper>
<iron>10</iron>
</house>

Then you will have to write a script to read the xml file and convert it to a class structure that
you can use in your C# code, you can do this using System.Xml.Linq; Research it a bit.

Here is a quick setup that still needs some modification, but I feel like this goes way over your head.

    public class Recipe
    {
        public int Id; // The house id
        public Dictionary<CraftingResource, int> RequiredResources;

        public Recipe(Dictionary<CraftingResource, int> resources)
        {
            RequiredResources = resources;
        }
    }

    public enum CraftingResource
    {
        Iron,
        Copper
    }

    public interface IItem
    { }

    public class CraftingItem : IItem
    {
        public CraftingResource Resource;
        public int Amount;
    }

    public class Inventory
    {
        public List<IItem> _items = new List<IItem>();

        public List<T> GetItems<T>()
        {
            return _items.Where(f => f is T).Cast<T>().ToList();
        }
    }

    public class Player
    {
        private static Player _instance;
        public static Player Instance
        {
            get
            {
                return _instance ?? (_instance = new Player());
            }
        }

        public Inventory Inventory = new Inventory();
    }

    public class CraftingSystem
    {
    private Recipe[] Recipes;

    public CraftingSystem(Recipe[] recipes)
    {
        Recipes = recipes;
    }

        public void Build(int houseId)
        {
            var houseRecipe = Recipes.FirstOrDefault(f => f.Id == houseId);
            if (houseRecipe == null) return;

            // Check if we have the resources
            var playerCraftingResources = Player.Instance.Inventory.GetItems<CraftingItem>();
            foreach (var resource in houseRecipe.RequiredResources)
            {
                var reqResource = playerCraftingResources.FirstOrDefault(f => f.Resource == resource.Key);
                if (reqResource == null)
                {
                    // Player doesn't have a resource
                    return;
                }

                if (reqResource.Amount < resource.Value)
                {
                    // Player doesn't have enough of this resource
                    return;
                }
            }

            // Remove resources from player

            // Building logic of the house

        }
    }

Create a function that will check whether you can build a certain building or not:

bool CanBuildHouse() {    
}

For simple conditions, you can use a simple if statement:

bool CanBuildHouse() {
    if (wood > 10) return true;
    else return false;
}

For more complex conditions, use multiple if statements, each checking for the single condition and exiting the function with a false result if it isn’t met:

bool CanBuildHouse() {
    if (copper < 10) return false;
    if (iron < 10) return false;
    return true;
}

Ok, so first of all, you may want to move your raycast just inside the “Input.GetMouseButton(0)” so you don’t throw raycasts every frame as it’s kind of expensive.

Second, you are only checking for one resource! Does your building support multiple require resources, because in this code it looks like it doesn’t. If your building also has a list/array of required resources you will have to throw in second ‘for’ to check every one of them. Here is an example:

foreach (ResourceItem requiredResource in thisBuilding.required)
			{
				if (!resources.Any(x => x.resource.Name == requiredResource.resource.Name))
				{
					return;
				}

				foreach (ResourceItem yourResource in resources)
				{
					if (yourResource.resource.Name == requiredResource.resource.Name)
					{
						if (yourResource.amount < requiredResource.amount)
						{
							return;
						}
					}
				}
			}
            //your building code here

Ok, now for an explanation:

  1. I converted your Building.required to an array or list so you can actually require multiple resources per building.
  2. resources.Any check is a safe check if you actually have that resource in your resource list. This may not be necessary if you are confident that you will always have all possible resources listed, but I thrown it in because why not. ‘Any’ is part of System.Linq namespace
  3. This will return from your Update method if at any point the condition will not be met, so you are 100% that after the first ‘foreach’ ends you do have enough resources. Write your building code under the first ‘foreach’ where I put a comment
  4. I used ‘foreach’ because I don’t like writing ‘for’, do as you like it doesn’t matter much in this case
  5. Consider using ‘enum’ for your resource names, this way you will make your code a lot more readable and prevent any typo in the future. Also Unity has a nice way of displaying enum fields as dropdown list in the inspector