How to make a modular buying system?

Hi,

I’m making a basic 2D clicker game and I have ran into a problem.

I want my “buying” system to be modular.

What I mean by this is that in the inspector, I can specify how many elements there are, set the values of those elements individually (e.g one’s “cost” is set to 1 and another to 5) and make the buttons appear (with those names, values etc.) a set distance between one another.

I have tried class arrays but then when I try to make them instantiate I get lots of errors.

Thanks in advance.

Having written one myself, start from a general “Product” class, and work from there.

For instance:

public abstract class Product : MonoBehaviour 
{
	public string Name = "Product";
	public string Description = "No Description";
	public Texture PreviewImage;
	/// <summary>
	/// Attempts to buy the product. Returns true if it was successful, returns false with a error message if not.
	/// </summary>
	/// <param name="callback">Callback.</param>
	public abstract bool TryBuy(out string error);

	/// <summary> Returns the price string of a product. e.g. "100 Coins" </summary>
	/// <returns>The cost string.</returns>
	public abstract string GetCostString();

	public virtual bool IsAlreadyPurchased()
	{
		return false;
	}

	public virtual bool Purchaseable()
	{
		return true;
	}
}

Then extend it for each product you want, e.g.

public class ShinyThing : Product
{
	public int Cost = 10;

	//Class that loads/saves player coins to a file.
	PlayerFundsHelper fundsHelper;

	void Awake()
	{
		fundsHelper = new PlayerFundsHelper();
	}

	public override bool TryBuy(out string error)
	{
		Funds playerFunds = fundsHelper.GetFunds();
		if (playerFunds.Coins < Cost)
		{
			int missingCoins = Cost - playerFunds.Coins;
			error =  "Not enough funds. You're missing " + missingCoins + " :("));
			return false;
		}

		playerFunds.Coins -= Cost;

		//Save the results
		fundsHelper.SetNewFunds(playerFunds);

            //!!!Insert code here to add shinyThing to your player's inventory!!!
            
		return true;
	}

	public override string GetCostString()
	{
		return Cost + " Coins";
	}

}

Finally, write a class that finds all the product classes you created in the scene and add it to a list. This one works by looking for Product Monobehaviours on children gameobjects.

public class Store : MonoBehaviour 
{
	List<Product> products;
	public List<Product> Products { get { return products; } }

	// Use this for initialization
	void Start () 
	{
		initialize();
	}

	void initialize()
	{
		//Now search for products, and add them to the products list.
		products = new List<Product>();
		products.AddRange(this.GetComponentsInChildren<Product>());
		products.AddRange(this.GetComponents<Product>());
	}


}

Then to buy something…

Store store = FindObjectOfType<Store>();
//Attempt to buy the first product in the store
string error;
if (! store.Products[0].TryBuy(out error))
{
      Debug.LogError("Purchase failed: " + error);
}
else
{
            Debug.LogError("Yay the product was bought");
}

Of course, all of this will change depending on the nature of your game.

To create your list of UI Buttons. Have another class that iterates over the products and generates a UI prefab in a scrollview. Then pass each product to a class on that prefab, and make it so pressing the button purchases that product.