Create a Drag N’ Drop Match Game Mechanic in Unity 2021 URP
In this article we’ll create a drag and drop match game mechanic with Unity’s built-in UI system.
Essentially, we’ll make sure that the item either moves to an acceptable slot or “snaps back” to its original position.
We’ll start with a Canvas, background Image, empty element with Vertical Layout Group for items, some item Image elements recycled from the last article, and a text field.
The DropItem Class/Script
We’ll build off of our existing scripts from the previous article.
For the DropItem class, add a field to hold the name of items we want to allow to snap to the Slot.
A simple if/then check and we’ve created a system where our slots will only allow the correct items to snap onto them.
NOTE: You could also do this as a tag comparison after tagging your items.
For our example, let’s use Item_03, a prefab from the previous article that has a blue book as its image.
Type that into Slot_1’s “Allowed Item Name” field in the Inspector.
NOTE: Since we won’t be instantiating these at runtime, we won’t get names that end with “(clone)”.
If you go with that approach, either use tags or check only the beginning of a game object’s name with “gameobject.name.StartsWith(“Item_03”)” in your code.
We also want to be able to drop any or all items into the “Items” Vertical Layout Group element in our scene.
To accommodate this, we’ll ad an OR statement in our if/then check that will allow any item if _allowedItemName is “All”.
Add the DropItem script component to the Items element and set Allowed Item Name to “All”.
We can see that it is working so far, except that the slot can hold more than one item.
We could add a text label and increment/decrement how many items are in each slot or we can prevent more than one item being in a slot.
Let’s do the latter.
The DropItem Class/Script
First, we’ll use a temporary Transform variable in the OnDrop() method to hold the item Transform now that we are modifying it at least three times.
We’ll also track with the _isFull class variable when the Slot is occupied, and set this value as needed.
The public SetIsFull() method will be called from our DragItem class on the item in question.
In the Start() method, we want to iterate through any child elements that are present when the game starts and set their DragItem scripts slot variable assignments.
The DragItem Class/Script
There’s quite a bit of code for us to add into the DragItem class.
This class needs to track the slot it is assigned to and was assigned to.
It needs to reset the isFull class variable on the Slot it leaves by calling SetIsFull() method on the slot’s DropItem class.
When the item begins to drag, we remove its _slotGo assignment.
When the item ends its drag movement, we check if _slotGo is still null and snap it back to the original slot if that is the case.
If it was dropped on a slot, the DropItem class of that slot will have set _slotGo to match that slot.
If the old slot has a capacity limit, we reset that slot to empty.
We could certainly make this more complex and add in functionality for each slot to have a variable number of max items, but we’ll live it as either 1 or infinite for this example.
We can see when running the game that our slot occupancy tracking is working as desired except that a blue book in Slot_1 cannot return to the Items slot.
If we delay checking _slotGO in OnEndDrag() method of the DragItem class, we can avoid conflicts with the OnDrop() method in the DropItem class which also set _slotGO.
Another issue is that for some reason the “Allowed Item Name” on my Items element had lost the value of “All” so I added that back in.
Now if we hit play, we should see our prototype working as desired!