Card Match Demo
v1.0
This is a simple version of a classic game β find two matching cards from the face-down cards on the board. The goal here is to do it in as few moves as possible. Press play, and tap on the cards to see how you do!
This demo showcases how to use actions to set and get things like PlayerPrefs, setting values at runtime on Actions, and more.

Start Screen
On the initial screen, we have a "Start" button and a high score, which is held on the High Score object under the Canvas. This has an ActionOnEnable component, which executes the ActionExecutor list as soon as the object is enabled.

The TMPSetTextFromPlayerPrefsAction is used here to pull a value from PlayerPrefs and set that, along with optional Prefix and Suffix values, to the Text Mesh Pro text object.
The Start button, also under Canvas, has an ActionRunner which drives the "Wiggle" motion. It also has an ActionOnTap to handle the player input β either a tap or a click with the mouse works.

The last action is SetPlayerPrefsAction, which we use to clear out the current games score. The two SetGameObjectActive actions will set some objects inactive, and some active.
The first action is TriggeUnityEventAction. This action exposes any number of UnityEvents that you'd like, and calls them. In this demo, we call the UICardDealer.Deal() method on the Dealer object.
Game Screen
The dealer deals 28 cards into the scene. The Card prefab has a UICard class with an ActionExecutore onDealActions. The Deal() method is called when these cards are instantiated.
The first thing we do is pass the targetPosition value, a Vector2, into the onDealActions. The SetFieldOverride method takes a Type of Action (RectTransformPositionAction), and then the field name that we want to affect, and the value to assign. There are other similar methods that allow you to use a UID or other values to set data onto Actions.
Then, we call onDealActions.Execute(this), which starts the actions execution. For these cards, we will play a "deal" audio clip with PlayAudioClipAction, and then move the card into position with the RecTransformPositionAction.

We move to the targetPosition in 0.33 seconds, with the curve assigned to positionCurve. Keep in mind the targetPosition value is set and will not be (0,0).
Cards
The Card prefab will be given one of 14 different faces when they are dealt. The prefab has an ActionOnHover component, which exposes an ActionExecutor for Hover Enter Actions, Hover Stay Actions, and Hover Exit Actions.
We have a RectTransformScaleAction in both the Enter and Exit execution lists. One will make the cards grow slightly, the other will make them scale back to normal size.
The cards also have an ActionOnTap component. This holds a "Tap Card" group of actions. We've put these actions in a group so that we can add Conditionals before we run the actions.

There are two conditionals, which must both pass in order for the Tap Card actions to execute.
First, we do a Custom Value Check on the target, which will look for an IConditionalValue component, which will have a GetConditionalValue() method on it. The UICard component is IConditionalValue, and has the required method:
Using the IConditionalValue on one of your components is a great way to enable custom Conditional checks when using Juicy Actions. Your logic in the GetConditionalValue method can be as unique to your project as you'd like.
We return false when this card is not selected, which fulfills the requirement for the first Conditional check.
The second check is looking for a Blackboard Value. In this case, if the value of cardsSelected is less than 2, then we pass the check and can proceed. This keeps us from selecting more than 2 cards at once.
GameController has the UICardMatchController component. The UnityEvent called by the UICard ultimately will trigger the CheckForMatch() method, when there are two cards selected at once.
If the two cards do not match, they each have their noMatchActions executed on UICard.cs. This flips them over with an audio clip.
If they do match, then the matchedActions are triggered.

We perform a number of actions β the first three all trigger at the same time, but the third has a 1 second timeBeforeNextAction, which gives these a full second to complete their animations. We scale the card down, rotate it, and reduce the opacity until the card is invisible.
Afterward, we disable a number of components before we destroy the Card object.
If all cards have been matched, the end game is triggered!
We hope this simple game has helped demonstrate the use of some key logical Actions, including some that add wonderful game feel / juice to your project.
Demo ScenesLast updated