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.
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.