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

Instantiate and Destroy help

Discussion in 'Scripting' started by tgraef, Apr 2, 2015.

  1. tgraef

    tgraef

    Joined:
    Feb 9, 2015
    Posts:
    11
    I am in the process of making a craps game. I have a "+" & "-" button that is supposed to increase your bet by $5. This works as far as adding and subtracting from the actual number, but I need chips to show on the screen to indicate the value, and where your bet is located. My "+" button works great, it increases my bet and instantiates a red chip on the table. the - button will remove a red chip from the table. I'd like to have some type of update method that detects 5 red chips ($5 dollars each) and deletes all of the red chips and adds a green chip($25 each). Below is my current code to add to the passline
    Code (CSharp):
    1.     public void AddPassLineChips() //Adds chips to the Pass Line
    2.     {
    3.  
    4.         Bet = passline._passlinebet;
    5.         Instantiate(RedChip);
    6.         _redchipcountPL++;
    7.     }
    This is my code to remove
    Code (CSharp):
    1.     public void RemovePassLineChips() //Removes Chips from the pass line.
    2.     {
    3.         //passlinechips = GetComponent<PassLine> ()._passlinebet;
    4.        
    5.         Debug.Log ("Remove Chips on table");
    6.       //  Destroy(GameObject.Find("redchip(Clone)"));
    7.         Destroy(GameObject.Find("redchipPL(Clone)"));
    8.         _redchipcountPL--;
    9.     }
    This is my update code that is called in the public void Update() function.
    I want to make it where it detects the amount of chips on the table, and if 5 red are on the table, add 1 green chip and remove the 5 red chips.
    Code (CSharp):
    1.     public void UpdatePassLineChips()
    2.     {
    3.         Bet = passline._passlinebet;
    4.         Debug.Log("BlackChip: " + _blackchipcountPL);
    5.         Debug.Log("GreenChip: "+  _greenchipcountPL);
    6.         Debug.Log("RedChip: " + _redchipcountPL);
    7.         Debug.Log("WhiteChip: " + _whitechipcountPL);
    8.  
    9.             if (_whitechipcountPL == 5) {
    10.                 Instantiate(RedChip);
    11.                 _whitechipcountPL = 0;
    12.                 _redchipcountPL++;
    13.  
    14.             }
    15.             if (_redchipcountPL == 5) {
    16.                 Instantiate(GreenChip);
    17.  
    18.                 _greenchipcountPL++;
    19.                 _redchipcountPL = 0;
    20.                
    21.  
    22.             }
    23.        
    24.     }
    Thank you in advance for any suggestions or comments.
     
  2. GroZZleR

    GroZZleR

    Joined:
    Feb 1, 2015
    Posts:
    3,201
    Store the objects as they're created in a List<> and use that list to keep track of them that way. This will also give you the benefit of not having to rely on strings to find and destroy them.

    First, declare your lists near the top of your script with all the other variables:
    Code (csharp):
    1.  
    2. // declare your lists near the
    3. protected List<GameObject> redChips = new List<GameObject>();
    4.  
    When you add a chip, store it in the appropriate list:

    Code (csharp):
    1.  
    2. GameObject chip = Instantiate(RedChip) as GameObject;
    3.  
    4. redChips.Add(chip);
    5.  
    To destroy the chips, simply loop through the list and empty the list when you're done (remember to clear the list or you'll run into trouble):

    Code (csharp):
    1.  
    2. foreach(GameObject chip in redChips)
    3.      Destroy(chip);
    4.  
    5. redChips.Clear();
    6.  
    You can also keep track of the amount of chips using the Count property of a List<> so you don't have to keep track of them separately with your _redchipcountPL variable. (redChips.Count)
     
  3. tgraef

    tgraef

    Joined:
    Feb 9, 2015
    Posts:
    11
    A couple of questions. the command instantly instantiates a red chip. Is there a way to apply this to a the variable correctly so I can call it with the redChips.Add(chip); command?
    Code (CSharp):
    1. GameObject chip = Instantiate(RedChip) as GameObject;
    Also what would be the code to remove a singular red chip from the "-" button?
    Code (CSharp):
    1. redChips.Remove(chip);
     
  4. GroZZleR

    GroZZleR

    Joined:
    Feb 1, 2015
    Posts:
    3,201
    I don't understand your first question. Can you try to rephrase it?

    You're on the right track for removing a single chip but you didn't call Destroy(). Try this:
    Code (csharp):
    1.  
    2. if(redChips.Count > 0) // make sure there are any red chips first
    3. {
    4.      GameObject chip = redChips[redChips.Count - 1]; // get a reference to the last chip in the list (the one most recently added)
    5.      redChips.Remove(chip); // remove it from the list
    6.      Destroy(chip); // remove it from the game
    7. }
    8.  
     
  5. tgraef

    tgraef

    Joined:
    Feb 9, 2015
    Posts:
    11
    Ok, after reading your second reply I think I understand now. So chip isn't a variable you are declaring at the beginning of the code, its a variable that you are changing for each function. Cause I tried the command redChips.Remove(chip); but it wasn't doing anything. But now that you are specifying chip right before that code... it makes sense. Ok you have really helped me. I can now succesfully add chips, remove chips, and once their are a certain amount of chips it will delete all of the red chips and create a green chip. Great. I haven't started this process yet, but now I just have to think about how to subtract a red chip when I only have a green chip. Thanks again, I really appreciate the help.
     
  6. tgraef

    tgraef

    Joined:
    Feb 9, 2015
    Posts:
    11
    Sorry to double post, but I was thinking about removing chips once they have been compiled. When I remove 1 Green Chip I'll need to add 4 red chips. I saw the AddRange command, and wasn't sure if this is what I would need to add it or if I should add them a different way. Thanks again
     
  7. GroZZleR

    GroZZleR

    Joined:
    Feb 1, 2015
    Posts:
    3,201
    I'm glad it's helping out.

    To create multiple chips, just use a loop:
    Code (csharp):
    1.  
    2. for(int i = 0; i < 4; ++i)
    3. {
    4.      GameObject chip = Instantiate(RedChip) as GameObject;
    5.      redChips.Add(chip);
    6. }
    7.  
    That will create 4 red chips and add them to the list.
     
  8. Gamba

    Gamba

    Joined:
    Feb 8, 2015
    Posts:
    29
    In my opinion, and from a gameplay perspective, it might be more user friendly to let your player add chips in the denomination he/she chooses, and then let them exchange chips of a denomination as a secondary input. It will also be less technically challenging to execute because you won't be mixing the logic of two distinct functions ( adding/removing money and denomination conversion).

    However, if you continue down your path, you might think about making a list for each type of chip (red, green, etc.). Then you can perform the exchange logic a little easier based on rules you can expose to the inspector. Below is an example of what you could do. It doesn't scale well if you add more denominations though. Perhaps you could make the whole thing easier to extend with inheritance.

    Code (csharp):
    1. using System.Collections.Generic;
    2.  
    3. public int redChipsToGreenChips = 5;
    4. public int greenChipsToBlackChips = 5;
    5.  
    6. private List<RedChip> redChips = new List<RedChip>();
    7. private List<GreenChip> greenChips = new List<GreenChip>();
    8.  
    9. public void AddRedChip()
    10. {
    11.     if ( redChips.Count + 1 == redChipsToGreenChips )
    12.     {
    13.         for ( int = i; i < redChips.Count; i++ )
    14.         {
    15.             Destroy( redChips[i] );
    16.         }
    17.         redChips.Clear();
    18.  
    19.         AddGreenChip();
    20.     }
    21.     else
    22.     {
    23.         redChips.Add( Instantiate( RedChip ) as RedChip );
    24.     }
    25. }
    26.  
    27. public void AddGreenChip()
    28. {
    29.     if ( greenChips.Count + 1 == greenChipsToBlackChips )
    30.     {
    31.         for ( int = i; i < greenChips.Count; i++ )
    32.         {
    33.             Destroy( greenChips[i] );
    34.         }
    35.         greenChips.Clear();
    36.  
    37.         AddBlackChip();
    38.     }
    39.     else
    40.     {
    41.         greenChips.Add( Instantiate( GreenChip ) as GreenChip );
    42.     }
    43. }
    44.  
    45. public void RemoveRedChip()
    46. {
    47.     if ( redChips.Count > 0 )
    48.     {
    49.         Destroy( redChips[0] );
    50.         redChips.RemoveAt( 0 );
    51.     }
    52.     else
    53.     {
    54.         RemoveGreenChip();
    55.     }
    56. }
    57.  
    58. public void RemoveGreenChip()
    59. {
    60.     if ( greenChips.Count > 0 )
    61.     {
    62.         Destroy( greenChips[0] );
    63.         greenChips.RemoveAt( 0 );
    64.         for ( int i = 0; i < redChipsToGreenChips - 1; i++ )
    65.         {
    66.             AddRedChip();
    67.         }
    68.     }
    69.     else
    70.     {
    71.         RemoveBlackChip();
    72.     }
    73. }
    74.  
     
  9. tgraef

    tgraef

    Joined:
    Feb 9, 2015
    Posts:
    11
    Ya, I actually successfully made it work properly with multiple lists for each chip. I was able to make it convert, and on removal make it convert to the proper amount. If I am successfully able to make this work, I thought a good platform would be an app, which would be better for touch. I am eventually planning on having the user change the units they are betting, but at this point I am just focusing on making a working game and having the user only changing 1 $5 units at a time This seems simpler to me, but maybe I am misunderstanding what you said. If you want an example of what I have so far... Just know that only the PassLine, and PassLine odds are working
    https://www.dropbox.com/sh/jxcri18w0hbvf1a/AACyPTGMeEgUKb76-FQ7l-Dja?dl=0

    A question that does relate to this:
    1. I currently only have the passline bet working with chips, but I am going to be replicating this same "smart chip" for all of my other bets. I've always heard if you have to write the same script multiple times then you are probably doing it wrong, so my question is With different posiitions of the chips on the Craps table, how could I apply this same logic? In the particular script I'm working on, it is using public prefabs, I was initially planning on creating prefabs at the multiple locations, and then applying similar scripts to organize the chips for that location.

    TBH, this is my first time making anything significant on my own (I've followed several of the tutorial projects) and have just a couple logical questions about lists or arrays and how I could use them. Not sure if I should just add those questions to this post, create a new one, or if pm would be better. Once again, thanks for the input and suggestions.


    Below is the code that Checks to what chips are on the table and updates them
    Code (CSharp):
    1.     public void UpdatePassLineChips()
    2.     {
    3.         Debug.Log("white chips: " + whiteChips.Count);
    4.         Debug.Log("red chips: " + redChips.Count);
    5.         Debug.Log("green chips: " + greenChips.Count);
    6.         Debug.Log("black chips: " + blackChips.Count);
    7.         if (whiteChips.Count == 5)
    8.         {
    9.             foreach (GameObject whitechip in whiteChips)
    10.                 Destroy(whitechip);
    11.             whiteChips.Clear();
    12.             redChips.Add(redchip);
    13.         }
    14.         if (redChips.Count == 5) {
    15.            foreach (GameObject redchip in redChips)
    16.                Destroy(redchip);
    17.            redChips.Clear();
    18.            GameObject greenchip = Instantiate(GreenChip) as GameObject;
    19.            greenChips.Add(greenchip);
    20.          
    21.         }
    22.  
    23.         if (greenChips.Count == 4) {
    24.             foreach (GameObject greenchip in greenChips)
    25.                 Destroy(greenchip);
    26.             greenChips.Clear();
    27.             GameObject blackchip = Instantiate(BlackChip) as GameObject;
    28.             blackChips.Add(blackchip);
    29.         }              
    30.     }
    Below is the current code I am during removal of chips.
    Code (CSharp):
    1.     public void RemovePassLineChips() //Removes Chips from the pass line.
    2.     {
    3. //       GameObject redchip = Instantiate(RedChip) as GameObject;
    4. //        redChips.FindLast(redchip);
    5. //        redChips.FindLast(redchip);
    6.  
    7.         if (blackChips.Count > 0 && greenChips.Count == 0) {             //Removes 1 black chip and adds 3 green and 4 chips.
    8.             GameObject blackchip = blackChips[blackChips.Count - 1];
    9.             blackChips.Remove(blackchip);
    10.             Destroy(blackchip);
    11.             for (int i = 0; i < 3; i++)
    12.             {
    13.                 GameObject greenchip = Instantiate(GreenChip) as GameObject;
    14.                 greenChips.Add(greenchip);
    15.             }
    16.             for (int i = 0; i < 5; i++)
    17.             {
    18.                 GameObject redchip = Instantiate(RedChip) as GameObject;
    19.                 redChips.Add(redchip);
    20.             }
    21.         }
    22.         if (greenChips.Count > 0 && redChips.Count == 0)    //Removes 1 green and adds 4 red chips.
    23.         {
    24.             Debug.Log("Removing Green Chip");
    25.             GameObject greenchip = greenChips[greenChips.Count - 1];
    26.             greenChips.Remove(greenchip);
    27.             Destroy(greenchip);
    28.             for (int i = 0; i < 5; i++)
    29.             {
    30.                 GameObject redchip = Instantiate(RedChip) as GameObject;
    31.                 redChips.Add(redchip);
    32.             }
    33.         }
    34.         if(redChips.Count > 0)
    35.         {
    36.             GameObject redchip = redChips[redChips.Count - 1];  // Selects the last chip in the list
    37.             redChips.Remove(redchip);       // Removes the last chip in the list.
    38.             Destroy(redchip);               // Destroys the GameObject for the RedChip
    39.         }
    40.        // GameObject redchip = redChips[redChips.Count - 1];  // Selects the last chip in the list
    41.        // redChips.Remove(redchip);       // Removes the last chip in the list.
    42.        // Destroy(redchip);               // Destroys the GameObject for the RedChip
    43.       //  Debug.Log("Removed Chip");
    44.  
    45.  
    46.     }
     
  10. Gamba

    Gamba

    Joined:
    Feb 8, 2015
    Posts:
    29
    Sounds fine. Duplicate code is often indicative of bad software design, but I've always been of the opinion that it's better to get functional and then refactor to remove "bad smells" later. Duplicate code aside, I'd rather see you pull out those magic numbers in the for loops and turn them into member fields that you can then edit in the inspector or at least find and change easily at the top of the file if you decide not to make them public. If you ever decide to change the exchange rate, it will be a pain otherwise; especially as code size grows.

    Best of luck!