Idk If it will help you, but: copy this code (separate the classes into files) and try it in Unity:
- Create some item prefabs;
- Create some Combination assets (using item prefabs);
- Create a empty GameObject and attach Crafter component;
- Assign those combinations that you’ve created;
- Start the game and try combinations using firstItemPrefabSlot and secondItemPrefabSlot;
- Press C to craft the current result if there’s a result the result item prefab is instantiated, otherwise nothing happens.
- Be attempted to console logs to understand what is happing.
Sorry for lack of explanation about how this system works, but take a look at the code and try to get it.
public class CombinationUtility {
// As you can see here, this code doesn't depend on the order of arguments,
// so if you have a combination that takes a Iron and a Wood both Iron+Wood and
// Wood+Iron will have the same result.
public static int CombineHashes(GameObject lhs, GameObject rhs) {
Assert.IsTrue(lhs && rhs);
int lhsHashCode = lhs.GetHashCode();
int rhsHashCode = rhs.GetHashCode();
int greatestHash, lessHash;
{
if (lhsHashCode > rhsHashCode) {
greatestHash = lhsHashCode;
lessHash = rhsHashCode;
}
else {
greatestHash = rhsHashCode;
lessHash = lhsHashCode;
}
}
int hash = 17;
hash = hash * 31 + greatestHash;
hash = hash * 31 + lessHash;
return hash;
}
}
[CreateAssetMenu]
public class Combination : ScriptableObject {
public GameObject firstItemPrefab;
public GameObject secondItemPrefab;
public GameObject resultPrefab;
public int GetCombinationHash() {
Assert.IsTrue(firstItemPrefab && secondItemPrefab);
return CombinationUtility.CombineHashes(firstItemPrefab, secondItemPrefab);
}
public bool IsValid() {
return firstItemPrefab && secondItemPrefab && resultPrefab;
}
}
public class Crafter : MonoBehaviour {
public Combination[] combinations;
private Dictionary<int, GameObject> m_CombinationsDictionary = new Dictionary<int, GameObject>();
public GameObject firstItemPrefabSlot;
public GameObject secondItemPrefabSlot;
private int m_PreviouslyCombinationHash;
private GameObject m_PreviouslyResult;
private GameObject m_CurrentResult;
private void Awake() {
// As the combinations are registred in the Awake method, you'll not able to add or remove combinations when the game is running.
if (combinations != null) {
for (int i = 0; i < combinations.Length; i++) {
if (combinations*.IsValid()) {*
// Registre combinations!
m_CombinationsDictionary.Add(combinations_.GetCombinationHash(), combinations*.resultPrefab);
}
}
}
}*_
private void Update() {
// Example
if (Input.GetKeyDown(KeyCode.C) && m_CurrentResult) {
GameObject newItem = Instantiate(m_CurrentResult);
Debug.Log(“New item has been crafted.”);
}
}
// We don’t need to calculate the hash every frame, so I used FixedUpdate.
private void FixedUpdate() {
if (firstItemPrefabSlot && secondItemPrefabSlot) {
int combinationHash = CombinationUtility.CombineHashes(firstItemPrefabSlot, secondItemPrefabSlot);
// combination changed
if (m_PreviouslyCombinationHash != combinationHash) {
m_CombinationsDictionary.TryGetValue(combinationHash, out m_CurrentResult);
if (m_PreviouslyResult != m_CurrentResult) {
OnResultChanged();
m_PreviouslyResult = m_CurrentResult;
}
OnCombinationChanged();
m_PreviouslyCombinationHash = combinationHash;
}
}
}
private void OnCombinationChanged() {
// You can Update UI here.
Debug.Log(“Combination has been changed.”);
}
private void OnResultChanged() {
if (m_CurrentResult == null) {
Debug.Log(“Invalid combination.”);
}
Debug.LogFormat(“{0} + {1} = {2}”, firstItemPrefabSlot.name, secondItemPrefabSlot.name, m_CurrentResult.name);
}
}