Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
2
Question by Lodos3 · May 15, 2012 at 10:00 PM · c#shuffle

Card Game [C#]

Hi everyone...I'm new to all of this, especially Unity3D. I started to design a pack of cards i could use for a game idea i have, Basically i want to have a card show up randomly when you tap a button on the screen (Android / IoS). Essentially giving you a shuffled pack feel, But... i want the cards called to be removed from the Random List of cards that Haven't been called, that way the same card won't show in the same game, until Reset.

Could anyone point me in the right direction with this?

I've made all the cards using Photoshop and imported them onto a Plane (Of which i made a prefab). How would i assing a specific number (array?) to each of these Card Prefabs...allowing me to call them to position randomly using a button?

Thanks in advance.

Comment
Add comment · Show 3
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Drakestar · May 16, 2012 at 01:51 PM 0
Share

How is this question different from the question you already asked at http://answers.unity3d.com/questions/253031/random-tag-call-script-c.html? Please close (or append to) the old question if you need more information.

avatar image AlucardJay · May 16, 2012 at 02:06 PM 0
Share

mmm, I didn't know this was a duplicate question. Perhaps you should read and try those answers , there's alot of good info there actually. And also leave comments to those that answered your other question , if you don't understand the scripts they provided , just politely mention that you need some explanation to help you learn and use Lists for yourself.

avatar image AlucardJay · May 17, 2012 at 03:21 PM 0
Share

see my last comment on @whydoidoit 's answer. Then check my answer (with screenshots).

2 Replies

· Add your reply
  • Sort: 
avatar image
2
Best Answer

Answer by AlucardJay · May 17, 2012 at 03:14 PM

I have edited the answer to include all considerations in the comments. First though, make sure your script name is the same as the class name (e.g. public class DeckOfCards : MonoBehaviour -> script name should be DeckOfCards) :

 using UnityEngine;
 using System.Collections;
 using System.Collections.Generic;
 
 public class DeckOfCards : MonoBehaviour
 {
     public List<GameObject> deck = new List<GameObject>();
 
     private List<GameObject> cards = new List<GameObject>();
     private List<GameObject> hand = new List<GameObject>();
     private int cardsDealt = 0;
     private bool showReset = false;
 
     void ResetDeck()
     {
         cardsDealt = 0;
         for (int i = 0; i < hand.Count; i++) {
             Destroy(hand[i]);
         }
         hand.Clear();
         cards.Clear();
         cards.AddRange(deck);
         showReset = false;
     }
 
     GameObject DealCard()
     {
         if(cards.Count == 0)
         {
             showReset = true;
             return null;
             //Alternatively to auto reset the deck:
             //ResetDeck();
         }
 
         int card = Random.Range(0, cards.Count - 1);
         GameObject go = GameObject.Instantiate(cards[card]) as GameObject;
         cards.RemoveAt(card);
         
         if(cards.Count == 0) {
             showReset = true;
         }
         
         return go;
     }
 
     void Start()
     {
         ResetDeck();
     }
 
     void GameOver()
     {
         cardsDealt = 0;
         for (int v = 0; v < hand.Count; v++) {
             Destroy(hand[v]);
         }
         hand.Clear();
         cards.Clear();
         cards.AddRange(deck);
     }
 
     void OnGUI()
     {
         if (!showReset) {
             // Deal button
             if (GUI.Button(new Rect(10, 10, 100, 20), "Deal"))
             {
                 MoveDealtCard();
             }
         }
         else {
             // Reset button
             if (GUI.Button(new Rect(10, 10, 100, 20), "Reset"))
             {
                 ResetDeck();
             }
         }
         // GameOver button
         if (GUI.Button(new Rect(Screen.width - 110, 10, 100, 20), "GameOver"))
         {
             GameOver();
         }
     }
 
     void MoveDealtCard()
     {
         GameObject newCard = DealCard();
         // check card is null or not
         if (newCard == null) {
             Debug.Log("Out of Cards");
             showReset = true;
             return;
         }
         
         //newCard.transform.position = Vector3.zero;
         newCard.transform.position = new Vector3((float)cardsDealt / 4, (float)cardsDealt / -4, (float)cardsDealt / -4); // place card 1/4 up on all axis from last
         hand.Add(newCard); // add card to hand
         cardsDealt ++;
     }
 }

Now here's where you drag and drop your card prefabs. Look in the inspector and you'll see Deck : Size : 0 .

alt text

Now change the 0 to 52. you should have the second screenshot.

alt text

This is where you drag and drop into the list. So ignore my last comment, you really should do it this way , and not the long-hand way =]

@whydoidoit this is from your JS answer, I hope you don't mind. I just needed a place to upload screenshots. I saw your link on another qn (orbit cam), I think it's really nice that you are sharing scripts. Thanks , I shall be browsing your 'site later. All the best =]


inspect 1.png (21.4 kB)
inspect 2.png (26.1 kB)
Comment
Add comment · Show 8 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image whydoidoit · May 17, 2012 at 03:17 PM 0
Share

You go ahead :) No problem...

avatar image Lodos3 · May 20, 2012 at 02:39 PM 0
Share

I tried to convert the OnGUI Javascript posted above to C#

     using UnityEngine;
     using System.Collections;


     public class Deal : $$anonymous$$onoBehaviour {
     void  OnGUI (){
         if(GUILayout.Button("Deal")) {
            GameObject newCard = DeckOfCards();
            newCard.transform.position = Vector3.zero; }
             }
             }


It isnt working tho =/ ... how can i run the script you gave me with the cards so that when i click a button .. its runs the script , eventually getting to the end and then changing to a reset button ... allowing me to start a fresh deck.

avatar image AlucardJay · May 20, 2012 at 05:03 PM 0
Share

I updated the answer with the buttons. But when you reset, the previously instantiated cards are Not destroyed.

avatar image Lodos3 · May 20, 2012 at 05:10 PM 0
Share

Excellent :P , i just need to work out how to get them to destroy :) thanks guys...this has been a massive learning curve for me lol. i hope to be helping out people like me verysoon .. il keep you guys updated on my progress :)

ty again!

avatar image AlucardJay · May 20, 2012 at 05:35 PM 0
Share

The 'Reset' button should show when all the cards have been dealt. It is displayed when the boolean is set to true :

    if(cards.Count == 0) {
      showReset = true;
    }

I just updated the answer to include a 'GameOver' button. I have added another list 'hand' , that stores all the cards that have been dealt. This will be useful in a card game, esp with this example showing how to destroy the cards in the 'hand' list.

Show more comments
avatar image
0

Answer by whydoidoit · May 15, 2012 at 11:08 PM

You could create a script with a list of prefabs, use the inspector to make it 52 long and then drop the prefabs into each slot. That gives you 52 cards that you can access.

Your then need to make a copy of the deck and deal out the cards one at a time in random order, removing it from the copied deck.

This script might help:

 #pragma strict

 import System.Collections.Generic;

 var deck : List.<GameObject>;

 private var cards : List.<GameObject> = new List.<GameObject>();

 function ResetDeck()
 {
     cards.Clear();
     cards.AddRange(deck);
 }

 function DealCard() : GameObject
 {
     if(cards.Count==0)
     {
         return null;
         //Alternatively to auto reset the deck:
         //ResetDeck();
     }
     
     var card : int = Random.Range(0, cards.Count-1);
     var go : GameObject = GameObject.Instantiate(cards[card]) as GameObject;
     cards.RemoveAt(card);
     return go;
 }

 function Start()
 {
     ResetDeck();
 }

 function RemainingCardCount() 
 {
     return cards.Count;
 }

When you call DealCard it will create a new GameObject from the prefab - you'd then need to position it etc. After 52 cards it would start returning "null" or you could check the RemainingCardCount(). In the script you could delete the return null; line and uncomment the ResetDeck() line to have it automatically start again.

You would probably want to call this in an OnGUI function that would show your button and then position the created game object according to the camera you have and where you want the item to appear. A simple OnGUI might look like this:

 function OnGUI()
 {
     if(GUILayout.Button("Deal"))
     {
         var newCard : GameObject = DealCard();
         newCard.transform.position = Vector3.zero; //Replace with your location
     }
 }
Comment
Add comment · Show 8 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image AlucardJay · May 16, 2012 at 01:37 PM 0
Share

I just noticed , this answer is in JS , not C# =]

avatar image AlucardJay · May 16, 2012 at 01:56 PM 0
Share

@Lodas , if you drag your cards into individual var Transforms, then you'll have to do some setting up to load those cards into the deck List :

 public GameObject Club1;
 public GameObject Club2;
 public GameObject Club3;
 public GameObject Club4;
 
     List<GameObject> deck = new List<GameObject>();
     
     void LoadDeckList()
     {
         deck.Add(Club1); 
         deck.Add(Club2); 
         deck.Add(Club3); 
         deck.Add(Club4); // ect ect for all cards

     }

try using the method in the answer , load your card prefabs into the deck List. I have tried to convert the above answer to C# , but it is untested and could very well contain errors (C# is not my native) =]

 using UnityEngine;
 using System.Collections;
 
 public class DeckAndCards : $$anonymous$$onoBehaviour
 {
     List<GameObject> deck = new List<GameObject>();
     
     private List<GameObject> cards = new List<GameObject>();
     
     void ResetDeck()
     {
         cards.Clear();
         cards.AddRange(deck);
     }
     
     void DealCard() : GameObject
     {
         if(cards.Count == 0)
         {
            return null;
             //Alternatively to auto reset the deck:
             //ResetDeck();
         }
     
         int card = Random.Range(0, cards.Count - 1);
         GameObject go = GameObject.Instantiate(cards[card]) as GameObject;
         cards.RemoveAt(card);
         return go;
     }
     
     void Start()
     {
         ResetDeck();
     }
     
     void RemainingCardCount() 
     {
         return cards.Count;
     }
 }
 
avatar image whydoidoit · May 16, 2012 at 02:09 PM 2
Share

To use the List in either JS or C# you just need to attach the script to a GameObject and view it in the inspector. When you expand Deck it will say 0 items, change this to 52 and you will get 52 slots. Drag the cards into those slots.

avatar image Lodos3 · May 16, 2012 at 05:30 PM 0
Share

I've done this, i attached it to a Blank plane called DealCard. The prefabs are in the slots ready to go...But how do i define the list?

avatar image AlucardJay · May 17, 2012 at 01:44 PM 0
Share

Ok, I am guessing this help has stopped because you don't quite understand : "attach the script to a GameObject and view it in the inspector. When you expand Deck it will say 0 items, change this to 52 and you will get 52 slots. Drag the cards into those slots". That's ok, list's and arrays are hard to get your head around when starting.

The advice you have been given is to Forget putting all your cards into separate Transforms in the Inspector, and put then into the List deck in the Inspector. This is the best method by far, soo much extra typing doing it your way.

However , if you want to write some code that populates List deck, I can help. But first you need to change your typecasting . What this means is you are putting your cards into a variable that is typecast as a Transform. e.g. public Transform Diamond1; Now if you look at the List it is typecast as GameObject. e.g. List deck = new List();

Can you see Transform and GameObject? To put Diamond1 into (the List) deck, the Diamond has to be typecast as GameObject , or the deck has to be typecast as Transform. I suggest you store the GameObject, as you can access all the components from this typecast (inc transform).

Here is the Long method for populating the list. You'll need to do the other suits (just the same as clubs):

 using UnityEngine;
 using System.Collections;

 public class DeckAndCards : $$anonymous$$onoBehaviour
 {
     List<GameObject> deck = new List<GameObject>();

     private List<GameObject> cards = new List<GameObject>();
     
     public GameObject Club1;
     public GameObject Club2;
     public GameObject Club3;
     public GameObject Club4;
     public GameObject Club5;
     public GameObject Club6;
     public GameObject Club7;
     public GameObject Club8;
     public GameObject Club9;
     public GameObject Club10;
     public GameObject Club11;
     public GameObject Club12;
     public GameObject Club13; // you can do the other suits!

     void LoadDeckList()
     {
         deck.Add(Club1); 
         deck.Add(Club2); 
         deck.Add(Club3); 
         deck.Add(Club4);
         deck.Add(Club5);
         deck.Add(Club6);
         deck.Add(Club7);
         deck.Add(Club8);
         deck.Add(Club9);
         deck.Add(Club10);
         deck.Add(Club11);
         deck.Add(Club12);
         deck.Add(Club13);
         
         Debug.Log(" List deck = " + deck); // this should show your List deck in the console, and show that the cards have been added
     }

     void ResetDeck()
     {
         // NOW load the List deck first
         deck.Clear();
         LoadDeckList();
         
         //
         cards.Clear();
         cards.AddRange(deck);
     }

     void DealCard() : GameObject
     {
         if(cards.Count == 0)
         {
            return null;
             //Alternatively to auto reset the deck:
             //ResetDeck();
         }

         int card = Random.Range(0, cards.Count - 1);
         GameObject go = GameObject.Instantiate(cards[card]) as GameObject;
         cards.RemoveAt(card);
         return go;
     }

     void Start()
     {
         ResetDeck();
     }

     void RemainingCardCount() 
     {
         return cards.Count;
     }
 }
Show more comments

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

9 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Multiple Cars not working 1 Answer

Distribute terrain in zones 3 Answers

Random Shuffle Listing 2 Answers

List woes. (C#) 1 Answer

Initialising List array for use in a custom Editor 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges