DeckStacker Cards
DeckStacker provides a template card prefab (setup to be a traditional western-style card) to get you started, and to navigate the system’s particular requirements.
Here is some information to help you get started working with DeckStacker, and to help you understand what is and is not mutable in what makes a Card.
Card - A Packet of Information
While making DeckStacker, I went about organizing information around the idea that Cards need to have a packet of information that is unique to themselves.
Typical info managed by the Card Prefab and associated scripts:
- Gameplay info
- What does the card mean to the game?
- What art is displayed on the card?
- Transform info
- What is the place and orientation of the card?
- Card state info
- Is the card face up or down?
- Is the card selected?
- Is the card moving, and in what way is it moving?
- What Stack does the card belong to?
Generally, card games place a lot of significance on individual cards. Each card has a place, and a meaning. This was the fundamental understanding I used when approaching this system.
One of the advantages to this is that the placement and organization of cards can hold a lot of gameplay meaning. Attaching information to a card, and understanding its context (like which Stack it’s contained in) will give you information about the game state.
If you think about it: This is basically a fundamental approach of most card games.
- What info is associated with a card?
- Where is the card on the board?
- What are the card’s neighbors, or what positional relationship does the card have with others on the board?
- Is the card in hand, or on the table?
- Is the card’s information visible, or is it hidden?
All of these questions are incredibly important in the universe of card games.
Hierarchy Breakdown
Card Diagram
DeckStacker was built with a particular prefab structure in mind. Let’s go through that structure and talk about each piece’s significance.
(I will be referring to the object names in the above diagram)
Object: DeckStacker Card
This is the object with most of the card’s DeckStacker scripts.
Let’s quickly run through each script and briefly describe them:
RectTransform
RectTransform
- This is a UGUI setup, and DeckStacker heavily leverages the UGUI system.
- Note the Width and Height fields
- This will be used in card spacing calculations, during Restack operations.
Canvas Group
Canvas Group
- This is used by the DSCardFader script for controlling card transparency
- Compatibility Note: Shaders used in DeckStacker Cards will need to be UGUI compatible in order for this fading tech to work, out-of-the-box.
DSCard
DSCard
- This script is mostly a communication hub for all the scripts, and is the gateway for any stack or gameplay script to get info from all the various components that make up the card.
- Additionally, there are a few odd-ball methods that it contains, such as ResetCard() which typically gets called when returning a card to its DSCardPool.
- This is also the default location for DSCardData, containing the card's stats.
DSCardArt
DSCardArt
- This manages the artwork displayed on the card.
- This script is setup for displaying traditional western-style cards.
- This is an obvious script to extend or replace in your game, unless you’re making a game that has this specific art in it.
DSCardFader
DSCardFader
- Controls card transparency and animating between transparency states.
- This is where the CanvasGroup, mentioned earlier, should be hooked up.
DSCardFlipper
DSCardFlipper
- Controls whether the card is face up or down, and animates card flips.
DSCardGrabber
DSCardGrabber
- “Card grabs” are typically user driven card movement, designed to not conflict with other types of movement
- Helps with keeping track of card grab behavior associated with a card.
- This is where you’ll find methods for:
- Starting a card grab
- Updating an ongoing card grab
- Ending a card grab
- See the section on DSButtonHandler, below, on how this can be driven by a mouse
- I recommend assigning the “Rotate Parent Y” object to the Grab Parent to avoid conflicting movements with other movement systems.
DSCardInput
DSCardInput
- Controls whether the card accepts user input, like taps or clicks.
- This also allows the developer to control which side of a card is interactable.
DSCardMovementHelper
DSCardMovementHelper
- There are a lot of different ways a card moves:
- Restack movement
- Custom movement
- Card Grabs
- Offsets
- Rotations
- Scales
- Moving a card between Stacks
- This script helps the various systems that move a card (mostly in DSCardMover) with card-specific information
DSCardSelector
DSCardSelector
- Handles card selection behavior and appearance
- ToggleSelect() will register a card as “selected” in DSRegistry.selectedCards and will signal to the DSCardTintHelper to tint the card a “selected” color (saved in the “DeckStacker Card Tint Settings” Scriptable Object)
- Other tint keys can be used with the ToggleSelect(string tintKey_) overload.
- You can also change the default key in the inspector of the card prefab.
DSCardTintHelper
DSCardTintHelper
- There will be times that you may want to change the color of your card.
- The prefab has a couple “Tint Images” setup that will overlay on top of your card, and apply a color to it.
- This is setup to take in DSCardTint objects, listed in the “DeckStacker Card Tint Settings” asset
- These tint objects can be retrieved by name.
- See DSCardTintSettingsSO and DSCardTintManager for more info.
- There are several options for how to trigger a card tint.
- See DSCardTintHelper for a full list of methods and their parameters.
Object: Rotate Parent Y
This object has 2 purposes:
- A rotation parent for card flipping
- See “Y Rotator” in DSCardFlipper
- A Transform parent for moving the card visuals, during a grab
- See “Grab Parent” in DSCardGrabber
Object: Rotate Parent XZ
This object has 3 purposes:
- Slight rotation during card flips (for more aesthetically pleasing card flips)
- Slight rotation (tilt) during card movement (also for more aesthetically pleasing movements)
- See “XZ Rotator” in DSCardFlipper for 1 and 2
- This is the object that moves during a card “offset”
- See “Offset Parent” in DSCardMovementHelper
Objects: Front Side, and Back Side
In UGUI, if we rotate the Y axis 180 degrees, we end up seeing the same side reversed, and still on top of the opposite side of the card.
Due to this quirk, we’ll need to deactivate the side of the card that is not visible. This is why there are 2 different parents for the 2 different sides of the card.
See “Front Side” and “Back Side” fields in DSCardFlipper.
Objects: Card Selection Tinter Front and Card Selection Tinter Back
Similar to the reason we need different parents for the front and back sides of the card, we’ll need different Image objects for card tinting for the 2 sides.
See “Tint Images” in DSCardTintHelper.
- A list of objects is used here in case you need additional flexibility in layering.
Object: Card Button
DSButtonHandler
This object is a transparent image, used as a button via its DSButtonHandler component.
Important Note: The DSButtonHandler uses Unity’s older input system, Input Manager. If you are using the newer Input System, then you’ll need to roll your own way of getting card input. This part of the prefab is optional, and fairly self contained, so you can mod in your own input tech.
For an alternative to Input System, I recommend InControl, by Gallant Games.
Here are some suggested uses for the different Unity Events available in the script:
- Short Click Event
- For normal “clicking on the card” stuff
- Long Press Event
- Secondary input, similar to a long press on touch screen devices.
- Be sure to note the “Long Press Time” field for adjusting how long a long press is.
- Start Drag Event
- This event fires when a drag is first detected.
- This was added primarily for starting card grabs.
- For mouse grabs: Use DSCardGrabber.StartGrabWithMouse()
- This can also be leveraged for making connections between cards or UI, such as dragging an arrow from a card to somewhere else on the screen.
- Dragging Event
- This is an event that fires every frame during a drag.
- This was added primarily for continuing card grabs.
- For mouse grabs: Use DSCardGrabber.OnGrabWithMouse()
- In the previous example about dragging an arrow from the card to somewhere else on the screen, this is where I would update the position of the arrow.
- End Drag Event
- This event that fires when the current drag event has ended.
- This was added primarily for ending a card grab.
- Use DSCardGrabber.EndGrab() for this.
- Hover Enter Event
- This event fires when a pointer (aka mouse) enters the Image’s rect, unobstructed.
- I like to use this event for initiating card offsets on cards that are interactable, to signal to the player that they can interact with those cards.
- Hover Exit Event
- Similar to “Hover Enter Event”, but the opposite.
- If you’re using the Enter version, you’ll want to consider an Exit event, as well.
An example of how all of these are used can be found in the “DeckStackerCard DemoCard”, used in the StacksDemo.
DSButtonHandler Used In StacksDemo
Objects: Card Blank, Card Image, Corner Image 1 and 2, Back Color
These are all Images that display the card art, setup for a traditional western-style card.
Not much else to say here, besides: See DSCardArt for how these are hooked up and updated.