Hi, I have a drink crafting mechanic where all my ingredients and mixed drinks are are enums, there’s a recipe list with all possible combinations of the drinks, and here’s the script used when the “mix” button checks the ingredients against the recipes:
public void Mix ()
{
//Debug.Log("Mixing " + string.Join (", ", Ingredients));
Drinks? result = DrinkMenu.Mix(Ingredients);
if (result.HasValue) {
Debug.Log ("You made " + result.Value.GetName ());
} else {
Debug.Log ("You didn't make anything.");
}
// Empty the ingredients after mixing them
Ingredients.Clear ();
indicator.SetInteger ("Fillbar", 1000);
}
What I need to know now is how to create a GameObject that matches the result. I’m working on a 2D game and all I need is for the object to display in the scene until a “serve” button is clicked. All of my mixed drinks are prefabs with an int id on them.
I’m very new with C# and I don’t know what I can write to make this work. Any help would be very appreciated!
Also, if it helps, here’s an example of the Drinks, and DrinkMenu.
public enum Drinks
{
[Description ("Vodka")]
Vodka = 0,
[Description ("Rum")]
Rum = 3,
// then mixed drinks
[Description ("MixedDrink1")]
MixedDrink1 = 117,
[Description ("MixedDrink2")]
MixedDrink2 = 102,
}
// And then there's the recipes,
public static class DrinkMenu
{
public static readonly List<Recipe> Recipes = new List<Recipe> {
new Recipe {
Ingredients = new List<Drinks> {
Drinks.Vodka,
Drinks.Vodka,
Drinks.Rum,
},
Result = Drinks.MixedDrink1,
},
}
I’d say a dictionary would suit you well in this case. Use your prefabs in an array and add the array elements to a dictionary, by the ‘id’. Their ‘Result’ value is the id, correct?
Use the dictionary to pull the gameobject from the key and instantiate it + place it where you’d like. 
Thanks,
I’m still not really any closer. Are there examples that can point me in the right direction? I feel like I start to get somewhere, lose the point and end up lost.
It feels like having these things stored as enums is much more trouble than it’s worth. Ask yourself: If you try to add a new kind of mixer, how many different places will you need to add it to make it work? I count 4, minimum. I don’t really see the reason an enum is being used at all here - it seems like just an extra step that makes everything harder. Just use the names directly.
A better idea might be to have a Mixer class, which is attached to a prefab which is placed in a folder (say, “Resources/Ingredients”) within the Resources folder. Then you can use Resources.LoadAll(“Ingredients”) to get an array of the ingredients you have available. If you need something like a dropdown, you can loop through that array and use its names.
Your recipe can store a list of string rather than a list of that enum, and load the ingredients by name (e.g. Resources.Load(“Ingredients/”+drinkName) )
In this system, adding a new ingredient to your game would be as simple as dropping in a new prefab - everything else would be populated from that automatically.
The enum trouble is due to the help of a variety of people trying to assist me with this who aren’t exactly well versed in Unity/game design itself. While I realize it’s a little unwieldy, and I would try to fix that in the future, I’ve been working on this game for a course in my university and this project’s due in a few short days and ALL I need is for it to be able to create a prefab based on the result of the mixer. At this point, dismantling everything to try and be more efficient isn’t really a possibility, though it’s certainly noted for later.
If it helps, I’m making a fairly simple visual novel. There doesn’t need to be more mixers. I definitely like what you’re saying about new ingredients just being a prefab in the future, but as of right now, all I need is for it to just create the drink sprite and I have no idea how to write that or set it up.
What’s your Recipe class look like?
Seems to me you’ll want to give it a comparison operator or function, which compares the list of ingredients. It’s probably easiest to compare if you sort the ingredients (sort them how it doesn’t matter, as long as it’s consistent), then you can just compare one to the other straight across the arrays.
From there you can just loop through your list of mixed drinks, compare the player’s recipe to the dirnk’s recipe, and if the same, create that one.
Here’s my Recipe class,
public class Recipe
{
public List<Drinks> Ingredients { get; set; }
public Drinks Result { get; set; }
// This tests if testIngredients contains all the same ingredients as this recipe.
// SequenceEqual() checks if two lists contain the same things in the same order,
// so I sort both lists so their orders don't matter.
public bool IsMatch (List<Drinks> testIngredients)
{
Ingredients.Sort ();
testIngredients.Sort ();
return Ingredients.SequenceEqual (testIngredients);
}
}
And this is the Shaker,
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class Shaker : MonoBehaviour
{
public Animator indicator;
public static Shaker Instance { get; private set; }
private List<Drinks> Ingredients = new List<Drinks> ();
void Awake ()
{
Instance = this;
}
public void AddDrink (Drinks drink)
{
Ingredients.Add (drink);
Debug.Log ("You added ingredient " + Ingredients.Count);
indicator.SetInteger ("Fillbar", Ingredients.Count);
}
public void Mix ();
{
Debug.Log("Mixing " + string.Join (", ", Ingredients));
Drinks? result = DrinkMenu.Mix(Ingredients);
if (result.HasValue) {
Debug.Log("You made " + result.Value.GetName ());
} else {
Debug.Log ("You didn't make anything.");
}
// Empty the ingredients after mixing them
Ingredients.Clear();
}
}
I have it presently reading on the console when a recipe is correct. I just can’t find any examples anywhere of how to take the result of that, and then display a GameObject.
OK, so you’ve got it converting a recipe into a drink name. You’re most of the way there - and I think we’re back to using Resources, only for the completed drink this time! Use the same method described above, but use the drink name in the path. Then you can Instantiate the loaded prefab (which should be the thing you want displayed).
Did ya get this working from @StarManta 's suggestions? 