Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice
  4. Dismiss Notice

Having Issues With My Prefabs which all use the same C# code

Discussion in '2D' started by epsilonomegastudios, Sep 24, 2020.

  1. epsilonomegastudios

    epsilonomegastudios

    Joined:
    Jun 18, 2020
    Posts:
    3
    So the idea of my game is having a bunch of asteroids in the game that you can mine from so the way I went about it was creating a prefab of all that the asteroid needs, having one was fine and when I added about 40 more I started having issues.

    So currently I only get one of the prefabs which works the way it was intended and the rest don't display their masses when the UI for them comes up as well as you're unable to mine them.

    The error I get on all of them except for the one which works is:

    ArgumentException: Item has already been added. Key in dictionary: 'Iron' Key being added: 'Iron'
    System.Collections.Hashtable.Insert (System.Object key, System.Object nvalue, System.Boolean add) (at <fb001e01371b4adca20013e0ac763896>:0)
    System.Collections.Hashtable.Add (System.Object key, System.Object value) (at <fb001e01371b4adca20013e0ac763896>:0)
    Asteroids.AssignPurity () (at Assets/Scripts/Asteroids.cs:249)
    Asteroids.Start () (at Assets/Scripts/Asteroids.cs:39)

    Or...

    ArgumentException: Item has already been added. Key in dictionary: 'Platinum' Key being added: 'Platinum'
    System.Collections.Hashtable.Insert (System.Object key, System.Object nvalue, System.Boolean add) (at <fb001e01371b4adca20013e0ac763896>:0)
    System.Collections.Hashtable.Add (System.Object key, System.Object value) (at <fb001e01371b4adca20013e0ac763896>:0)
    Asteroids.AssignPurity () (at Assets/Scripts/Asteroids.cs:249)
    Asteroids.Start () (at Assets/Scripts/Asteroids.cs:39)


    Same error but with the different two keys. Would this happen to be an issue with using a Hashtable? When you click on the different asteroids in the inspector they have different masses and different masses of each mineral, so clearly there is a separate instance of each script being run for each asteroid, which is what I want, but I don't understand why it's saying the item is already added.

    If each one runs separately wouldn't it be starting from no items added every time?

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.UI;
    5.  
    6. public class Asteroids : MonoBehaviour
    7. {
    8.     public Rigidbody2D rb;
    9.     public float rotation;
    10.     // Percentage of the Asteroid that is Metal
    11.     public float purity;
    12.     // Total List of Minerals in the game
    13.     public static List<string> Minerals = new List<string>();
    14.     // List of minerals in the Asteroid
    15.     public List<string> Mineables = new List<string>();
    16.     public Hashtable MineablesPurity = new Hashtable();
    17.     public float mineralPurity;
    18.     public float MaxPurity;
    19.     public float mass;
    20.     public List<float> MassOfMineables = new List<float>();
    21.     public static List<float> MinedAmount = new List<float>();
    22.  
    23.     //Mining UI
    24.     public GameObject miningMenuUI;
    25.     public Text platinumConcentration;
    26.     public Text ironConcentration;
    27.     public bool updateUI = false;
    28.     public Text platinumCargoMass;
    29.     public Text ironCargoMass;
    30.     public int timesMined = 0;
    31.     public bool UpdateMiningUI = false;
    32.     public bool MiningStarted = false;
    33.  
    34.     // Start is called before the first frame update
    35.     void Start()
    36.     {
    37.         PopulateMinerals();
    38.         AsteroidStats();
    39.         AssignPurity();
    40.         FindMasses();
    41.         //PrintList(MassOfMineables, Minerals);
    42.         miningMenuUI.SetActive(false);
    43.         StartCargoUI();
    44.         updateUI = true;
    45.  
    46.     }
    47.  
    48.     void Update()
    49.     {
    50.         rb.AddTorque(rotation);
    51.         if (updateUI == true)
    52.         {
    53.             MiningUIConcentrations();
    54.             UpdateMiningUI = true;
    55.  
    56.         }
    57.  
    58.         MiningUICargoMass();
    59.  
    60.     }
    61.  
    62.     private void OnTriggerEnter2D(Collider2D other)
    63.     {
    64.         if (other.CompareTag("Ship"))
    65.         {
    66.             PlayerController2D.mining = true;
    67.             miningMenuUI.SetActive(true);
    68.         }
    69.     }
    70.  
    71.     public void Undock()
    72.     {
    73.         PlayerController2D.mining = false;
    74.     }
    75.  
    76.     public void StopMining()
    77.     {
    78.         CancelInvoke("MineMinerals");
    79.         CancelInvoke("MiningUICargoMass");
    80.         MiningStarted = false;
    81.     }
    82.  
    83.     public void MineMinerals()
    84.     {
    85.             UpdateMiningUI = true;
    86.            
    87.         float drillRate = PlayerController2D.drillRate;
    88.             for (int i = 0; i < Mineables.Count; i++)
    89.             {
    90.             // You'll have to change this when adding More Minerals to the game
    91.             if (Cargo.CargoMass[0] + Cargo.CargoMass[1] > Cargo.MaxLoad)
    92.             {
    93.                 CancelInvoke("MineMinerals");
    94.                 CancelInvoke("MiningUICargoMass");
    95.                 MiningStarted = false;
    96.                 break;
    97.             }
    98.  
    99.             timesMined++;
    100.                
    101.            
    102.             float massMined = 0;
    103.  
    104.                 if (drillRate == 0)
    105.                 {
    106.                     massMined = 0;
    107.                 }
    108.                 massMined = Random.Range(0, drillRate);
    109.                 float checkLeftover = drillRate - massMined;
    110.  
    111.                 if (checkLeftover < 0)
    112.                 {
    113.                     massMined = drillRate;
    114.                     drillRate = 0;
    115.                
    116.                 }else
    117.                 {
    118.                     drillRate = drillRate - massMined;
    119.                 }
    120.  
    121.                 MassOfMineables[i] -= massMined;
    122.                 MinedAmount[i] += massMined;
    123.  
    124.         }
    125.     }
    126.  
    127.  
    128.     public void Mining()
    129.     {
    130.         if(!MiningStarted)
    131.         {
    132.             UpdateMiningUI = true;
    133.             InvokeRepeating("MineMinerals", 1F,1F);
    134.             InvokeRepeating("MiningUICargoMass", 1F, 1F);
    135.             MiningStarted = true;
    136.         }
    137.     }
    138.  
    139.  
    140.     public void StartCargoUI()
    141.     {
    142.         for (int i = 0; i < Minerals.Count;i++) {
    143.             MinedAmount.Add(0);
    144.         }
    145.         // You'll need to add more to these when you add more minerals types
    146.         string ironMass = Minerals[0] + " : " + MinedAmount[0].ToString("F3") + " Kg In Cargo";
    147.         ironCargoMass.text = ironMass;
    148.         string platinumMass = Minerals[1] + " : " + MinedAmount[1].ToString("F3") + " Kg In Cargo";
    149.         platinumCargoMass.text = platinumMass;
    150.  
    151.     }
    152.  
    153.     void FindMasses()
    154.     {
    155.         //This function will find the mass of the minerals and save it in a hashtable
    156.         for (int i = 0; i < Minerals.Count; i++)
    157.         {
    158.             float mineralMass = 0;
    159.             MassOfMineables.Add(mineralMass);
    160.            
    161.         }
    162.         for (int i = 0; i < Mineables.Count; i++)
    163.         {
    164.             float specificPurity = (float)MineablesPurity[Mineables[i]];
    165.             float mineralMass = mass * specificPurity;
    166.             MassOfMineables[i] = mineralMass;
    167.         }
    168.     }
    169.     // Create the text that shows the masses in the UI
    170.     public void MiningUIConcentrations()
    171.     {
    172.         // You'll need to add the other mineral concentrations here after adding them
    173.        
    174.         string ironMass = Minerals[0] + " : " + MassOfMineables[0] + " Kg";
    175.         ironConcentration.text = ironMass;
    176.         string platinumMass = Minerals[1] + " : " + MassOfMineables[1] + " Kg";
    177.         platinumConcentration.text = platinumMass;
    178.        
    179.     }
    180.     //update cargo load in mining UI
    181.     public void MiningUICargoMass()
    182.     {
    183.         // You'll need to add the other mineral concentrations here after adding them
    184.  
    185.         string ironMass = Cargo.MineralType[0] + " : " + Cargo.CargoMass[0].ToString("F3") + " Kg In Cargo";
    186.         ironCargoMass.text = ironMass;
    187.         string platinumMass = Cargo.MineralType[1] + " : " + Cargo.CargoMass[1].ToString("F3") + " Kg In Cargo";
    188.         platinumCargoMass.text = platinumMass;
    189.  
    190.        
    191.  
    192.     }
    193.  
    194.  
    195.  
    196.     void AsteroidStats()
    197.     {
    198.         // Create a random number of Minerals for the Asteroid based on total number of minerals
    199.         int MineralsLength = Random.Range(0, Minerals.Count);
    200.         // Add a random Mineral for every number of Minerals created above
    201.         for (int i = 0; i <= Mathf.RoundToInt(MineralsLength); i++) {
    202.             int rand = Random.Range(0, Minerals.Count);
    203.             Mineables.Add(Minerals[rand]);
    204.         }
    205.         // Remove Duplicate Minerals
    206.             RemoveDuplicates();
    207.        
    208.  
    209.         purity = Random.Range(0.010F, 0.999F);
    210.  
    211.         mass = Random.Range(70250000F,421500000F);
    212.  
    213.  
    214.         rotation = Random.Range(-5F, 5F);
    215.         rb.AddTorque(rotation);
    216.     }
    217.  
    218.  
    219.  
    220.     void RemoveDuplicates()
    221.     {
    222.         for (int j = 0; j < Mineables.Count; j++)
    223.         {
    224.             for (int i = 0; i < Mineables.Count; i++)
    225.             {
    226.                 if (j != i)
    227.                 {
    228.                     if (Mineables[j] == Mineables[i])
    229.                     {
    230.                         Mineables.Remove(Mineables[j]);
    231.                         break;
    232.                     }
    233.  
    234.                 }
    235.  
    236.             }
    237.         }
    238.     }
    239.  
    240.     void AssignPurity()
    241.     {
    242.         if (Mineables.Count > 0)
    243.         {
    244.             MaxPurity = purity - (0.001667F * Mineables.Count);
    245.             float totalPurity = 0;
    246.             for (int i = 0; i < Mineables.Count - 1; i++)
    247.             {
    248.                 mineralPurity = Random.Range(purity * .1F, purity * 1F / Mineables.Count);
    249.                 MineablesPurity.Add(Mineables[i], mineralPurity);
    250.                 MaxPurity = MaxPurity - mineralPurity;
    251.                 totalPurity = totalPurity + mineralPurity;
    252.             }
    253.             MineablesPurity.Add(Mineables[Mineables.Count - 1], purity - totalPurity);
    254.         }
    255.         else
    256.         {
    257.  
    258.             mineralPurity = purity;
    259.         }
    260.     }
    261.  
    262.     void PopulateMinerals()
    263.     {
    264.         Minerals.Add("Iron");
    265.         Minerals.Add("Platinum");
    266.     }
    267.  
    268.     void PrintList(List<float> table, List<string> List)
    269.     {
    270.         for (int i = 0; i < table.Count; i++)
    271.         {
    272.             Debug.Log(List[i] + " Mass : " + table[i]);
    273.         }
    274.     }
    275.  
    276.  
    277.  
    278. }
    279.  
    If you need any more information let me know, Thanks Yall.
     
  2. epsilonomegastudios

    epsilonomegastudios

    Joined:
    Jun 18, 2020
    Posts:
    3
    Update: So it was the Hashtable, so currently they are the baine of my existence.

    If anyone can explain to me what their purpose is that would be great because I currenlty think they're useless.