Card Game - Newbie needs some help

Hey guys!
So I just downloaded Unity a few days ago to make a table card game I like in unity.
But after “creating” the playmat (looks aweful haha) I encountered a few problems as a newbie in Unity.
Well, first things first let’s have a look on the playmat:

The red square is the pile that contains ALL cards and you draw cards from it to fill empty spaces in the middle panel so that there are always 5 cards in that panel.
The black pile is the players deck which contains 7x Card X and 3x Card Y. Like you can guess it will be shuffled and you draw 5 cards each turn (with some cards you might draw more or less).
Now my problems are:

  • How do I get my cards into my game/Unity? I have about 50 different cards in the red pile with different amount of copies of each like 5x Card 1, 8x Card 2, 3x Card 3 and so on. Programatically I’d make a card map with Cardobjects of each kind of card mapped to their name. Webbased I could have databases with a table that contains all kinds of cards. But how to get them into Unity?
  • After getting my cards into Unity… How to make a pile out of them? My first thought would be putting them on each other like you would in RL.
  • How do I shuffle my piles if needed?
  • How to draw a card from a pile like my deck? First thought would be using a plugin for path animations (saw something for that).
  • How to put them “ordered” in hand when drawn like in Hearthstone so the cards are kind of centered (saw a Tutorial for Drag and Drop where he showed something to order cards when dragging, maybe I could use that).

Sorry for so many questions but thank you for your help in advance! :slight_smile:

Many possible ways. I would make a card prefab with a script that changes the texture of the card depending on suit and number variables.

I don’t think the “like in real life” approach is best here. Just make a pile-looking thing and pretend the cards are in there. Attach a script that holds an array shuffled values and a public link to the previously mentioned card prefab to it or something.

As I said above, you could make it as easy as shuffling an array.

If you use the system I (vaguely) described above, you just remove the card value from array and instantiate a prefab with that same value. And yes as far as animation goes, you can use anything you find.

Something like a horizontal layout?

1 Like

Have you written the game logic for the cards or looked at any tutorials on C# card games?

As once you have your card game running logically e.g. so it can shuffle and draw cards then print out the hands in the console, it’s just a matter of drawing and animating the cards doing it on the display.

Unity has it’s own animation system and there are Tweening libraries API calls that can help a lot with moving things like cards from one place to another smoothly.

You do need to realise that the cards are just sprites and it is working out the UI/UX and turns or phases of the game that the user interacts with that will be needed. What the user can do each turn. Then you have your card game broken down into stages or steps that need to be implemented.

1 Like

It’s not enough to just change the texture. How do I get the cardeffect and values like costs to buy the card into it? Thought about a gigantic if for all cardnumbers and then do their stuff but that can’t be the way to go :smile: Or do you mean I make a prefab for each card and change the texture from back to front or the other way?

Yeah something like you see here:
Videoexample

Thanks for pointing that out. You’re right and I should do that. Bringing me to another question: Is it possible to code in C++ instead of C#?

Sort of. You can write C++ libraries and use them in Unity, but you need to write scripts in Unity to call into that code.

I wouldn’t recommend it anyway, as this use case wouldn’t take advantage of any of the benefits C++ has over C#.

There are literally too many ways to approach this to discuss. If you know C++, I’d say to think about how you’d go about adding information and functionality to cards outside of Unity, then apply the same approach here. Or do a bit of research into component oriented design and get some inspiration there.

Edit: I hope that didn’t sound dismissive or unhelpful. What I’m trying to get at is to not let the fact that you’re using Unity and it has its own Editor and so on stop you from thinking about stuff like a programmer (I assume you know a bit of that from your asking about using C++ instead). You’ve got a full .NET (Mono) environment here, you’ve just also got a bunch of extra stuff on top of it.

I already told you to attach a script to a card prefab.

No, I said make A card perfab (1), that can change it’s texture according to script values like suit and number.

Ahh so you mean that I create a card prefab that’s used for every card as template and create a script for each card available and add them when instantiating a card, right?

Ahh I think you think my card texture contains editable objects like a circle where I write the cost in, etc. but my cards are images that already contains everything so I just need to change the sprite according to cardname or something I guess.

No, create 1 script for all cards. We call variables variables for a reason. :slight_smile:

No.

Yes, I’m telling you you can change sprites with script.

Sry for being dull haha :smile: But how do I reuse a script for effects when the effects variate very hard like card A let you draw a card and card B is an attack. Shall I make a gigantic if statement to ask which card is used? Sry I am kinda confused :frowning:

But what do you mean then with changing by suit and values? Do you have an example? :slight_smile:

There are many ways to do this. You could create an abstract card class which contains all logic that can be applied to every card and then make derived classes for every card type (eg. Attack Card, Draw Card, Special Effect Card)

Make an IEffectScrip tinterface that will be a wrapper class for all events. Then the card can have a list of all IEffectScript references and you can choose then from the list depending on card name identifier. Continuation below.

I said “suit and value” because I assumed you’re talking about normal 52 card deck. You can have it much simpler.
Let’s say you use interger as identifier for your cards.
Then you can have a class in the card prefab script that will hold sprite names and use integers as keys.

[System.Serializable]
public class Card
{
    public int identifier;
    public IEffectScript effect;
    public Sprite sprite;
}

This way you can just fill up the list of Card-s in editor.

And then your Reveal method would look something line this:

public void Reveal(int identifier) {
    GetComponent<SpriteRenderer>().sprite = cardList[identifier].sprite;
    _effect = cardList[identifier].effect
}

OK It’s hard to judge what level people are at but why not start off with a new scene and…

  • Get one card to turn over when clicked.
  • Get a deck of cards to deal out n when clicked.

Then build up from there, card movement, player actions ect?

@FMark92
At first I wanna say: I really thank you :slight_smile: You are helping a lot and I understand more and more about your idea of a concept! :smile:

So I googled a bit about wrapper classes (never heard of that) but I am still not sure how you want to use that concept here. Let’s say we have 10 different cards with each having an other effect. I understand the Card Class and I think you let the card call a method like effect.useEffect(identifier) which then calls the effect from the effectlist, located in the IEffectScriptInterface (correct me if I am wrong), by the identifier. Or do you have a method for each effect in the IEffectScriptInterface and a List of References to the methods (if that is even possible) and then effect.useEffect(identifier) just calls the method behind the identifier in the list?

@Arowx

That rly sounds like a good idea and I will try that as soon as I understood FMark92’s approach of implementing the cards and their effects :slight_smile:

It’s already monday… Sorry for the late reply.

I was rushing when I mentioned wrapper class, sorry. IEffectScrip is an interface which CardEffect scripts then implement.
https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/interfaces/
Interfaces are useful in your case as you will be able to put all effect scripts into one Array of IEffectScript type.

That said, if you want CardEffect to have any of the MonoBehaviour functions (Awake, Start, Update…), interfaces will not work. This is because MonoBehaviour is already an interface. In such cases you can use abstract classes.
https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/abstract.

No, IEffectScrip (AND abstract EffectScript) is just a list of communication rules (and default method implementations if you are using abstacts)

Small example of abstracts:

public abstract class CardEffect [B]: MonoBehaviour[/B]
{
    public int effectId;
    public abstract void useEffect();
    public abstract void Update();
}
public class CardEffectDrawTwo [B]: CardEffect[/B] {

    public override void useEffect()
    {
        // transfer two cards from the deck to your hand hand
    }

    public override void Update()
    {
       Debug.Log(""+effectId); 
       // Just here to demonstrate you can use MonoBehaviour methods in abstract implmentations.
    }
}

And you will need to have CardEffect instances somewhere in the scene becasue unInstantiated effects can’t be referenced.

3301456--256110--upload_2017-11-27_8-0-13.png

I appreciate that you have placed the understanding of the concepts I have presented as a priority but don’t ever stop trying new or different things. @Arowx 's idea is sound. Make a minimum viable product first and then build on it. Debugging will also be a lot easier when you have a solid ground to stand on.

It’s okay :smile:

So I create a Script for each effect abd those implement the IEffectScript. Then I have an array that contains all this scripts and I’ll call them with the card identifier. But where do I save the array of the effects then or where do I create it to fill it with the effects?

So I just create a empty GameObject and instanciate the Effects there then I guess.

Yeah you’re right :slight_smile:
And yes I’ll do what @Arowx said.

Thanks you two!

Yes. Though, since your effects may or may not contain animations (I don’t know that) you might want to use abstract classes instead (automated Update() and stuff).

Into the Card script, which is attached to a prefab - that way array contents will be saved and every card instance will contain the full list of effect object locations.

You attach a new script and implement the IEffectScript in it, yes.

Good luck!

I think I finally got it now, thank you!

Shall I initiate the id, effect and sprite for the card in the Start() method or better use a constructor or even a own written init method? The problem I have is that I can’t/shouldn’t pass values to Start() :frowning:
I think a good way is to have an instance of the CardPile it came from in the Card, like the players deck, so it can interact with it like using an effect on it (draw Cards, search for a Card, destroy a Card, etc.). I’d have a ICardPileInterface then that want standard methods like drawCard implemented and the card will have something like this public ICardPileInterface cardPile;
I’d init this then in a constructor or init method.

Init method or constructor. Definitely.
Having a card pile abstract or interface seems like a good idea, yes.
Just one thing about the naming convention:
The “I” in the beginning of the class name already marks it as an interface. No need to write it twice. :wink:

After googling a bit I read that you shouldn’t use a constructor because it would be called multiple times when used in MonoBehaviour.
Read here: https://answers.unity.com/questions/862032/c-constructor-in-monobehaviour.html
So I’ll use init Methods :slight_smile:
I now made a SceneHandler Script that I attach to the background which will handle most actions like interacting with cardpiles or playing cards. Like this I read it should be easier for AIs to do player actions because they can just use the functions of differents scripts instead of simulate user actions if that would be even possible. The script also calls the init methods in Start(). What you think about this idea?

Constructors would work if you didn’t write effects as monobehaviour implementations. And with SceneHandler that’s still a possibility.

Not sure. As I imagined it, init only gets called when you have instantiated the card and know what card it is. If you have all cards instantiated and initalized at the beginning, having a cardpile is obsolete.
But do it anyway. The only way you’ll see if it works is by trying.:slight_smile: