Creating a Match 3 Game in Unity

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello and welcome in this video i'm going to show you how to create a simple match 3 game in unity engine the end result will be something similar to this so as you can see you can match three or more items or tiles together and we have score different scores based on the uh the item inside of each tile and we can match more than three or more tiles in different arrangements as you can see here this is a row and this is like an l shape and here we have another shape so it's pretty simple and uh fun concept so we will get started right now first um we'll need to download an asset from excuse me from the asset store called dotween it's a very powerful tweening and animation asset for unity it's free and it's very useful so we're going to download this let's go into unity and go ahead package manager select my assets search for dotween and select the free version if you have the pro version it's basically the same except for like the visual editors but we won't be needing this so we'll just use the free version let's click on import so uh once it's imported you'll see a panel that opens unlike a window that opens this panel um and we need to set up the assets so we do this by clicking on setup dotween now okay disable all these three modules and click on apply it's going to start compiling some stuff here and yep that's done now before closing the utility panel go to the preferences and we're going to change some settings here i'm going to set recycle tweens to true we're going to disable autoplay by setting autoplay from all to none we're going to change the a's to an outside i just prefer this you can choose whatever you like and we're going to keep auto kill on and we're going to change the settings location from assets resources we're going to change it to dotween resources so once you've done this let's close this window so you might notice i already have some assets here which is just a simple sound effect for when you collect the items or you match the tiles i will link this in the description and we have some sprites some cute animal sprites made by kenny you might know have heard of him he is a very generous asset creator and this asset's free on his website it's called animal pack i'm going to link it as well so when you go and download it consider becoming a patreon forum or donating some money so uh that's pretty much it for all the assets we'll be using in this tutorial let's get started by creating our scripts folder okay i'm going to create a script called bro create another one called um board okay create another one called title and finally for now we'll create a third or sorry fourth script called item and once this is created we'll just let the editor compile okay and now let's set up our editor uh so i'm building for fgl which shouldn't really matter you can build this on any platform so my camera is set up as follows you can pause the video and check the settings out so to create a simple match 3 board we're going to need ui canvas you can just call it canvas and rename the event system to be in the snake case i'm going to go inside the canvas change the ui scale mode to scale was with screen size you might want to keep it a constant whatever i'm just going to scale it with uh to the reference resolution of 1280 by 720 and move the match from the width all the way to the height so it matches depending on the width you might want to change this as well so it really depends on the platform or the device or like the operating system you're targeting so not the operating system just the device okay or the screen resolution uh in the canvas we're going to create an empty object and call it the uh board container i'm going to set it to fill the entire screen okay it's going to be an empty object just to hold our actual board element let's right click here and create ui image and call it board i'm gonna set it to fill the parent this is going to change in a second i'm going to set the source image to a background okay i'm going to go back to the board container and add some spacing from the left top the right the bottom so as you can see it's now 10 units from each uh 10 pixels from each uh side let's go back to the board object and let's go all the way down and click on add component let's search for um aspect ratio or large aspect it'll show you this component called aspect ratio feather let's select it and we're going to go to the aspect mode and make it fit in parent okay uh so just before we do this let's change this uh real quick so remove the component let's go up here set it to center okay set the width maybe like 512 512 add the uh component again and say fit and parent so this will basically make it uh i should have i could have made it from this aspect ratio uh field here this is just an oversight sorry so as you can see it will always be a square regardless of the resolution as you can see even with strange ones like this we're just going to stick with uh 16 to line aspect ratio so let's go and change the board background make it a little bit transparent and let's start work by creating our rows so a row is going to basically hold some tiles but to create this we need like a grid layout unfortunately the grid layout in unity doesn't allow like flexible spacing but this can easily be worked around by creating like by going inside this on this uh word object adding a vertical layout group okay we're going to set the batting from the left right top and bottom to 10. we're going to set the spacing to 10 as well i'm going to change child alignment to upper center i'm going to control child size width height okay we're going to use the child scale yes once you've done this we're going to right click here and create an empty object and call it brow so currently this row doesn't have really anything so we're going to add an um horizontal layout component to it i'm going to add any batting just going to make it uh change the spacing and make it down i'm going to change the child alignment to middle left going to as was like like previous change the control child size and make the width and height true use child scale true and go inside the raw object and just drag it sorry and select your object and drag it and drop it on your assets to create a prefab let's create a prefabs folder real quick let's drag it and drop it here so we now have a row prefab inside the row i'm just going to create a new tile and start a new game object and call it tile so our tile object is going to be very simple i'm going to use an image let's add an image component to it choose the source image to be the background image keep it sliced and inside the tile we're going to add another image and uh call it beckham okay i'm going to set it to fill but with some spacing as well okay we're going to choose the sprite the ui sprite and we're going to change the image type to sample this will change later it might look ugly right now but it will be fixed later on let's uh toggle use sprite mesh and preserve aspect so your tiles like the tile icons look better later on and be sure to disable the raycast target go back to your tile game object and add a component called button as you can see this will make our tile clickable let's change the fade duration to something like this and let's go ahead and create a prefab out of this tile object and depending on your game you might have five tiles per row ten thousand whatever so i'm just going to have five tiles per row let's apply the changes let's go select the route at five oh wait let me just make this a little bit easier on ourselves one two three four five so as you can see we can change the number of tiles to whatever we see fit but i'm going just to use five tiles per row now go back into the board and duplicate the road five times as well and as you can see we have a grid layout that is flexible if you were to go and change for example the aspect ratio here you might see that the cells change size as well and they retain their like position in the grid like or table like uh form i'm just going to keep it one so it's square once you have done this let's go and begin scripting first thing that we need to do is um go to our row script first we'll be using community engine we need to have a public sealed object sealed class right that inherits from mono behavior it's going to have a public field that's called ask of type tile array so let's go to tile and add the double square brackets to indicate that it's style and call it tiles this is pretty much it for the row class uh it's very simple but it's very useful and our game heavily depends on it so let's close the stroke class go back inside of unity select our row object and go into the prefab drag and drop our row script row component on here and drag and drop each tile here but beforehand let's go to the tile object go to the prefab itself edit add the tile script go back to the row and start adding the tiles to the tiles array and the row script so now we have five tiles and if we go back to the scene you can see that all the rows have the same thing applied to them um after we do this let's go inside the tile script remove all the code inside of it make the sealed class because we're not going to extend it in any way let's move then use directives and let's add some fields right here so first we'll need a field called public and x public and y which are the coordinates of the tile and the board space um let's go and add a public field of type item and call it item um let's go ahead and add a field of type public image from the unity engine.ui namespace i'll call it icon going to have a sorry another field of type button just call it button as well so this is pretty much it the basic tile script that we're going to have right now so let's go and do the item script so let's go into unity double click on item remove all the code inside and let's inherit from scriptable object cloud classes and let's add the attribute called create asset menu change set the menu name to equal match three items so this will make the will add a menu item when you right click or add a context action when you right click in the project window that allows us to create new item instances this will be shown right away but let's finish the class first let's go and add a public sprite icon let's call it item sprite anyways and let's go and before this field and the public and value so this value field over here is going to be how much this item gives us when we give this sorry gives us uh per match like for example if we match three uh tiles with this item if this value is three for instance then this match is going to give us nine points uh so that's pretty much it for the item class let's close it and let's close the tile class for now it's going to unity and as you can see when you right click in the assets folder create you'll see a new entry called match 3 and there is our item context create creation oh sorry item creation context action if we select it you'll see it creates a new item you can change the value and assign sprites to it so let's not do this right now let's delete this and let's go inside our port script this is the main thing this is the most important class in all of our project so as we do as we did before let's seal this class let's remove let's keep these name spaces we might need them right now let's add a public static board instance get private set this is a static property called instance that can only be set from excuse me inside this class this is basically like a singleton excuse me that we're going to use throughout the tutorial so it's useful to have instead of using like find game object or using text and messy stuff like this so let's go and add a private void awake which is a built-in unity [Music] as it's called magic method let's assign the instance to this and let's add some excuse me uh fields to our port um script first we need to we need to add a public row array call it rows we're going to have a public two-dimensional tile array we're going to call it tiles [Music] my name convention is that the fields that are not serialized and are public are going to be uppercase while the ones that are serialized are going to be lowercase you can follow whatever convention you prefer i just use this to make things a little bit more clear and since this isn't this styles field isn't going to be used by unity let's just turn it into a property that can only be set from inside this board class so let's go ahead and add some other fields like a public and width which is going to be the width of the board we're going to go ahead and say tiles dot get length zero so what does tiles.getlength mean normal arrays have a single length property which is the number of items inside this array but multiple multi-dimension arrays might have different lengths for each dimension so let's say for example you have a table it might have a different number of uh columns and different number of rows so the length isn't the same for these two different dimensions so this is what gate length and uh dimension like it length takes in an integer as a dimension does it returns the length of determining specific dimension so we have a public and length width and we have a public end height tiles get length and choose the first or like the second dimension as the like as a dimension to your turn its length um after this i'm just going to go ahead and start initializing our table or like tiles and the board stuff like this so private avoid start but you might say how do we oh excuse me notifications shut up okay how do we know the width and the height of the tiles array before we even like initialize it or create it well remember we have in our row class the styles array so we can return the we can like get the maximum number of rows or sorry of tiles in a single row and use this add width of our entire port uh this is a simple implementation you might have a game with variable row length or variable row size it's going to be a very simple change but we're going to stick with the maximum number of tiles in a row as a wrath so and this leads us to set tiles i'd like to set the tile array to be something like this so i'm going to create a new tile the width is going to be rows dot maximum which is an extension method from the system.link uh namespace i'm going to say row sorry right gonna return row.tiles.length and the height is going to be basically the number of rows that we have so i'm going to go ahead rows.length and that's pretty much it we just need to assign the tiles to their respective like uh cells or invices in the array and to do this let's go ahead and create a four var x sorry bar y equals zero y is less than width y plus sorry that's less than the height of our board y plus plus for our x equals zero x is less than the width x plus plus and here we're going to set the tiles to be tiles at x and y equals basically rows y dot tiles x so what this what this means is the tile at this x and y is going to be equal to the tile inside the row at the y index and the tile's index is going to be x so it's pretty simple uh thing let's remove the braces it's a symbol uh it's a pretty small 2d loop so once we do this we need to go ahead and start adding the icons and how to change the icon or item vertile so let's remove these extra two lines let's go inside our tile class let's change the item field here to be private okay let's add an underscore and let's go ahead and head here and add a public item item property it's going to return this item filled here and it's going to set f the item doesn't equal sorry equals the incoming value so if we already have the item assigned to the style don't do anything don't waste time processing this function otherwise let's set the item the item to the incoming value and let's set the icon that sprite to item let's write so this basically checks if we as i said before have assigned this item already to the style and if not it'll assign the item and change the icon automatically for us okay uh so let's go into our board here sorry let's go inside of unity editor the entity editor and wait until it compiles let's create a new script and call it item database so item data base okay wait until everything is compiled and the item database is going to be a simple uh helpful class so let's remove all the code that comes into it remove the dependency on the main moto behavior let's make it a static class and let's remove the collections and spaces and here what you're going to have is something a little unusual so first we're going to have a public static sprite array and we're going to call it um sorry item array i'm going to call it items we're going to be get a private set so it can be set from the outsiders class and we're going to have a private void static void initialize let's use the expression body method say items equals resources delude all items and the items folder so what this call over here will do is if let's go first to the ent editor and let's go ahead and create a new folder called resources and let's add a new item let's try a new folder called items and let's say we have a an item here called let's see graph let's assign the giraffe sprite to it let's give it a value five let's say we have multiple items here uh inside this items folder so what resources that loot all does is it grabs all of the um item assets inside of that folder and stores them into our items array so it's a little bit more convenient and easy to access but you might say how are we going to call this initialize method so the folks at unity gave us this powerful attribute called run time initialize unload which basically calls the static method um automatically for you at the specific moment of your application or games in this lifetime so as you can see here we have a runtime initialize unload attribute and it takes one of the one two three four five uh six um inun values here sorry five inum values here subsystem registration after assembly is loaded after scene load before scene load and before splash screen these options are pretty self-explanatory but we're going to go ahead and choose the before scene load so it does loot all of our assets before the scene is looted so once the scene is loaded we can easily access them without like having to wait for the assets to loot and stuff like this so that's pretty much it for the item database class let's go inside our board and again for each style let's just gonna add the brackets since our loop is going to have multiple blocks inside of it so make it more clear let's go uh tiles x y are going to store this in a variable so var tile equal rows y tiles x i'm going to set the tiles at the current coordinates to the tile we're going to set the tile dot item so as you can see what's exposed now is the property let's double click on this and let's say equals to item database dot items and that's we need a random item you know it might not be the best way to implement this uh like board initialization mechanic because you might get initial matches or no matches at all so it's kind of random you might want to follow uh or do something else like maybe check for each style and see if you wanna add uh the same item twice or not you wanna start with a specific layout it's all up to you in this tutorial i'm just gonna do random you know item picking so how do we do this so we index the items array using random dot range and we take the first argument as zero and the second one as item database that items.length so say we have five items it's just going to pick an item straight an index between zero and five and then return this index sorry this number okay and this number will be used as an index and return the item at that specific index okay so let's save our class let's go inside of unity let's add some more items i'm going to create items for all of the animals that we have we have the hippo monkey the parrot the penguin are they big and finally the snake strike and drop the snake sprite and i'm gonna give the snake three points but you know what two points only because snakes are bad joking i just kind of kind of afraid of snakes so uh as you can see we have now seven items and they should be randomly chosen let's just go to our tile prefab first and confirm that we have assigned all the proper values so this is isn't the case let's go ahead and do this it says sign the icon let's assign the button component and one important thing is the x and y we forgot to assign them and when we are initializing our port so let's go inside board.cs and assign the title uh specific coordinates let's remove this from here to the bottom say tile x equals x tile dot y equals y wait until the editor refreshes go inside of unity again excuse me and if we now run our game it should have sorry each title should have a different sprite let's go and see and they don't know for some reason let's check oh yeah because we forgot to assign our uh rows to our board instance so the mistake sorry we even forgot to add the port instance at all so let's drag the board script and add it to our port game object let's drag the rows and make sure that everything is in order because if you add some rows before others it might corrupt everything and everything will be kind of wanky so be sure to add everything in order let's run the game now and everything should excuse me have a random sprite which is perfect uh so this is the basic thing let's go ahead and now start adding like swapping and um popping the items or collecting the items i like all again calling it popping because you know items pop from the board and disappear and new items are generated uh let's go ahead and start doing this let's remove this you use new faces let's go ahead here and add a new public void select and it takes a tile as a parameter so we have a simple method called select that takes in a tile as a parameter but since our port game you can need to select two items to swap together we're going to add a couple of private fields here so private tile selected tile1 private tile selected title 2. or a better way would be to go ahead here and have a list so i need only list of tile i'm going to call it selection i'm going to initialize it in place i'm going to go all the way down here i'm going to do a couple of checks first i'm going to go ahead and say if selection dot count is less than two we return so any code after the statement over here if we didn't select two tiles will be ignored and before this we're going to go ahead and say selection dot add tile oh sorry tile um so and before we add the tile to the selection we should actually check if the style isn't already contained in the list so f selection that contains style not i'm going to say selection dot add type um so that's basically the first thing here but we need to go down and after the selection that count listen to uh check we're gonna go ahead and say selection with clear so after we have selected done all of our like matching and popping operations we're gonna clear the selection and to indicate that we did this let's go ahead and say debug dot log selected tile tiles at let's go ahead and print a tile coordinates let's go selection zero dot x and selection zero that's y and then we go ahead and have selection1.x and selection1.y if we go to the editor now we need to go to our tiles that's right tile script and in a start method so we're going to have a private void start inside of it we're going to add a callback or like uh yeah a callback to our button so button.unclick.listener so basically what this does is when i click on this button it will add like it will add a listener so when i click on the button it will execute the code that i add between these two parentheses so what the code will be is a simple lambda expression that does called board but for instance you see the singleton can be used now let's select this and what this does is basically tell the board to select this style let's convert it to an expression body and let's go inside of unity again um let's double check that we have assigned the button it's already here let's go and attach the console to the top here and let's run our game so we have these two tiles over here which is i think zero zero and zero one or one zero so let's check this zero zero and one zero so let's select them and see what will the console say and as you can see it correctly works so let's see i select this and this listen this and it works so this is our selection now for the swapping part which utilizes dotween let's close let's end the game mode let's save your project and let's go into rider and the board let's add a public avoid swap so what swabbing does is swap two tiles together let's say tile type one tile tile two um this function might be a little confusing so be sure to focus uh very well when i'm writing it i'm going to explain everything of course so first we need a reference to the first and second icon so icon one equals style one that icon of our icon to equal style to that icon i need a reference to each of the icons transforms so let's go icon one transform equals i could one transform and we need a reference to the second icons transform equals icon to the transform um and we need to change the swap from being a void to be an asynchronous task which is inside system.threading dot tasks namespace so basically what tasks is this is a very high level explanation i recommend that you go ahead and check more in-depth tutorials on these subjects but to sum it up a task is like a mini thread it executes something or let's say it's a core routine like a unity core routine it's something that runs in parallel and can be awaited delayed or run in a different thread but in our case it's going to be something that is run in parallel that we can wait for and you'll see how we're gonna utilize this so uh we're gonna go ahead and now start the animation how do we animate two sprites moving from one position to the other so here we're going to have a var um sequence oh no no no not a sequence sorry go ahead and have icon one excuse me very sorry quite confused here you have a var sequence equals dotween which is our the asset that we downloaded dot sequence i'm going to call sequence sorry a weight sequence dots play dot await for completion so what this does is turn our like awaits for our sequence to play and finish playing successfully so this is going to be useful so you can't like swap multiple time tiles at the same time and break the game basically so before we play it let's go in the middle here and add some tweens to the second to the sequence so let's go sequence dot join which basically happens between let's run in parallel to other tweens as well so we're going to say icon icon1 transform but to move to icon to transform that position let's introduce a constant up here that's going to hold the time it takes to finish the twins right between duration i'm gonna do 0.25 f let's go here say between duration let's go ahead and say dot join icon to transform the do move i can 1 3 transform dot position take three duration um one interesting thing about dog tween that it allows us to add uh callbacks when the animations are done so basically what happens right now is that the two two icons just move uh from one position to the other but nothing actually changes about the tile itself so we'll go ahead here and wait until the sequence is complete okay we're going to change the parents and the excuse me the parents and the icons of the child so the appearance of the icons and the icons of the tiles uh to do this let's go ahead here and say icon1 transform let's set parent to title to the transform since it moved to the second tile it's going to be its parent and the vice thing for the icon 2. so let's go icon 2 transform that's a parent tile 1 dot transform so this basically moves the changes the parent of the first icon to be the second tile and the second icon to be appearance to be the first tile okay um but this is not everything we're gonna go ahead and set tile 1 dot icon equals icon 2 and tile 2 dot icon equals icon 1. then after we set the icons we're going to change the items so we need to store the tile1 item in a temporary variable file tile1 item equals tile 1 dot item we're going to set tile 1 but item 2 equal to tile 2 item then tile 2 dot item to be equal to the variable that holds the value of the time one or the reference to the tile one item uh if we didn't have this variable if we change the taiwan item to be the second tile then attempt to use the second tile items to be the first files item it will just reassign the same value to it since now tile1 item refers to tile2 item this is kind of confusing but it's a real simple concept and this code over here is like explains it okay so that's pretty much it for um the swapping method let's go up here and change the select uh method to be asynchronous and let's await the completion of our swapping task which basically we're going to swipe between selection 0 and selection 1. uh if we go inside of unity now okay and we go to the scene view to confirm some stuff let's open the first and second tiles and keep an eye out on the hierarchy now let's play the game or enter play mode so let's swap the snake with the penguin and as you can see this icon now changed its parent and the tile did get let's go into debug mode did get the correct item assigned to it let's swap this in this maybe as you can see it works perfectly okay but right now there is no matching and stuff like this so let's go and implement this let's exit the play mode let's go inside of rider here and matching is going to require multiple things and it might get a little complex but hopefully i'll be able to explain it in a simple way so let's go here and add a couple of methods but not to implement them yet so private void can pop okay i'm gonna go and throw a new not implemented exception so basically you haven't implemented it yet that's going to return a boolean i'm going to have another private uh void that's going to going to be called bob and it's going to throw a new not implemented exception for now uh let's go into our tile cs and add a method uh let's sorry add a couple of properties first i'm going to have properties that return the adjacent tiles to the style so like the left the tile to the left the tile to the top button right and so on to do this let's go ahead and have a public tile left which is the left dial i'm going to go ahead and say port put instance the tiles at the current x minus one and our at our current y position um but this might return an out of range exception if you for example add the zero coordinate so we need to check for something we say if x is more than zero return this otherwise return null so if we are at zero we cannot return anything to our left because there is nothing to our left okay let's go and copy this and paste it and we're going to go ahead and top so i'm moving clockwise left top right bottom uh the top is going to be the same thing but uh the y here so i'm going to go with y if y is less than um the height of our like oh sorry is more than zero i'm going to go ahead and return the tile at our current position on the x-axis but above us on the y-axis because if you remember in our board um when we initialize it we go from small to big so the tiles at the lower numbers are above us okay let's go back to the tile and here we're going to have a public let's place the same code um right it's going to be this time and i'm going to check if x is more than zero you check if x is less than the number of tiles or the width of the board minus one so it's going to be like this x is less than board with instance what minus one we're going to return the tiles at our x plus one or null and finally for the bottom uh tile we're gonna go ahead and check if y is less than the height minus one we return y plus one okay and to return all of these at once we're going to have we're going to have a property called public array neighbors boards okay it's going to be a read on the property and it's going to return a new tile a all right here that's going to take left top right button twitter turns the neighbors in order okay each time it's called so it's not uh like it's not cached so this it won't be called a lot of times anyways but if you're gonna call it a lot of times i suppose you should store it in a local variable so let's go here now and add the function a function that returns the adjacent or the connected tiles to the style let's go here it's going to be a recursive function so you better again focus very well with me here so we're going to have a public list of tiles so tile get connected tiles and we're going to have a parameter a list of type tile sorry which take a list of tiles and let's call it exclude and it's going to be mobile default because it's going to be initialized by this method itself so let's go ahead and open maybe like paint let's create a new document real quick and let's go with the brush yeah so assuming we have a simple uh board like this okay very good drawing skills there let's say i want to match all the red tiles okay like this we have some yellow tiles here we have some green tiles down here let's use the pink as our like path drawing tool to zoom in so assuming we start here this style is going to look at its neighbors okay and a check if this neighbor for example is of the same type that is going to ask this neighbor to return all of its neighbors that are of the same type so this neighbor is going to go ahead and see oh this is not the same color that's the same type as me this is not sorry this is not and this is not so it's just going to return itself uh this style here is going to ask this style over here can you please return all of your neighbors that are of the same type it's going to say okay this is not so i'm going to take this it'll look here it'll find one of its cup uh kind so it'll keep repeating and say can you please find all your neighbors this will look down here say okay go down here and say okay this will go down here then say no and terminate so it is going to turn this this this this this and this and this one as well so let's go ahead and start implementing this so first we have a var result equals a new list of tiles and that contains this style initially so it's going to return itself in the list of connected tiles and let's return this result okay excuse me and this exclude list over here that we have a default to know we're going to check if exclude equals to no i'm going to say exclude equals a new title array that contains this style otherwise we're going to add the style to it so you might say what's the use of this exclusion list so let's go back to our uh paint 3d and let's look here let's remove all of these pink drawers purple drawings let's say we moved all the way to this tile over here so can you please tell me what your neighbors are so it's going to return this guy over here and this guy over here uh but we have already checked for the pair like this is our starting tile so if we keep checking for our neighbors we're going to enter a stack overflow or an infinite loop so this is going to refer to this this is going to refer to this and so on and so forth because this neighbors this quite a messy explanation there but the exclusion lasts sorry the exclusion last makes sure that this tile for example never double checks for this tile so if it know if it's this style has already been checked or have been or have been already added to the results list it'll be ignored it'll just look for the neighbors that haven't already been added like this one and this one will check for this one only and this will check for the next one only and so on so let's go into in writer here and let's do a little loop so let's go here for each neighbors go ahead and say neighbor and the neighbors we're going to skip the neighbor if so if neighbor equals to no or exclude that contains the neighbor so if the neighbor is excluded ignore it okay or the neighbor.item is not the same type as my item i'm going to continue okay otherwise the results array is going to so we're going to add to the results array arrange which is basically going to call neighbor get connect to tiles and pass in the exclusion list so as you can see now let's go all over the function again the result list contains all of the connected tiles to the style so let's do it like if we have a tile at the beginning of the board at it will return all of the tiles connected to the style directly or via its neighbors okay uh the exclusion lasts prevents us from entering an infinite loop okay the forage loop over for each loop over here loops or iterates over all of our neighbors and it checks if this neighbor is null ignore it if it's excluded ignore it if it's not of the same doesn't like have the same item ignore it otherwise return me all of the tiles connected to our neighbor okay um we can see this in action so if i go the port here let's go real quick and add let's see a function let's go private avoid update i'm going to check if input sorry and put get key down keycode dot a for example okay sorry it's gonna go turn we're going to highlight or make all of the tiles grow for example all the connected tiles to the first tile in the top left corner will be highlighted let's go here and say for each um tiles at zero zero dot connected tiles i'm gonna say connected tile dot icon that do so the transform to do scale to 1.25 f and let's scale it um so it's going to take the play duration okay let's remove the brackets and this basically says when we click sorry when you press down the a button it's going to iterate all over all the tiles connected to the one in the top left and i'm going to scale them to one and quarter times okay let's go back in unity let's play the game and unfortunately we don't have you know what we can arrange our tiles so just for demonstration if i press a you can see it returned all the tiles connected to uh this peg over here of the same type if i switch this it won't return anything like it won't scale the monkey let's move the monkeys and arrange them in a way like this for example and press a is going to as you can see a highlight or monkeys and this is a very like uh perf uh performant method like it doesn't do that much recursion and it's uh panel to end okay so if you have a very large board you can iterate it over an occur routine and it won't really like take that long okay so that's pretty much it for the getting the connected tiles now it's time for popping or matching as people like to say let's review this update function and let's go to our can pop method here and add some guide so how will kampup work is going to do a two-dimensional loop so for y equal is less than the height y plus plus let's use var here let's say 4 by x equals 0. x is less than the width x plus we're going to say if tiles at the current x and y that get connected tiles okay if the connected tiles minus the initial tile which is basically the tile itself so i'm going to check let's go ahead and paint three to explain everything so when this style starts checking for connected tiles it builds a list with itself being the first item so let's see let's assume we're gonna match these three items or check if the matches are more than um three or like we have more than two matches sorry more than two items connected to us which means this one and this one for example or these two over here are connected to this one so this will be this one here and this will be that one here so we skip this first item and we just check for the rest of the connected tiles so if they are more than two or they are equal to that's a match otherwise it's not okay let's clear this let's go with writer again and say so basically what the skip does it just skips the specified number of items so we skip the first one and then we count them using the extension method dot count okay and check if it's more than or equal to then we return true let's remove the braces remember the braces here as well and return false by default so if we can't find any pops we just return false uh here in the select method we're going to wait the swapping and we're going to say we're going to say if we can pop after we have swapped the items then sure keep the swap otherwise revert this flapping operation so if can pop let's say i'm gonna call the pop method here otherwise we're going to swap back a weight swap back the selection zero and selection one so as you can see we're going to swap the tiles back if we can't find any matches okay and the pop method itself okay excuse me for this uh for these delays so if the pub method uh sorry the pub methods method itself is going to be very simple it's going to do the same thing as the can pop but it's just going to do a little bit more and like in the sense that it's going to pop the tiles replace them with new ones and so on okay um so let's go ahead here and say var x that's right yeah four of our x equals zero or y equals zero y is less than the height y is plus four var x equals zero x is less than what x plus plus we're going to store the style in a local variable so for title equals tiles sorry at the current x and y um and let's go ahead and see let's say var matches or connections equals ceramic connected connect tiles say tile.getconnect tiles we are going to go ahead and say if connectedtiles.count is less than 2. so if there isn't if like the connected tiles to this one is less than two uh we ignore it there is no popping to do here okay so let's go ahead and say continue otherwise we're going to pop the tiles how okay we're going to go ahead and have a var sequence it's going to equal let's call it deflate sequence which basically we're just going to scale the icons down so it shows that um it has plot okay deflate sequence equals dot twin sequence and we're going to iterate so four sorry for each um connected tiles we're gonna go and call connect tile let's remove this here and we're gonna say deflate sequence dot join connect tile dot icon transform the 2 scale to vector 3.0 so scale all the way down and take between duration okay that's the first thing then we go ahead here okay say await deflate sequence yeah sorry we need to make this uh method asynchronous so here's a um deflate sequence dot play dot async await for completion or async wait for completion okay once the deflation sequence is complete we're going to iterate over the connected tiles and randomize their item okay so we're gonna go ahead here i'm going to save for each again um connect tiles connect tile and say connect tile item equals item database dot items random at range zero return database items.length just like we did above and while we're inside this loop to we need to add the inflation sequence so we're going to go ahead and say await inflate sequence equals dotween sequence um oh sorry bar and flight sequence equals dotween.sequence i'm going to go ahead and add or join between to the inflation sequence sorry so you can make the tile that icon that transformed to scale all the way back up to uh vector 3.1 is going to take between duration then we go ahead here and say await um what's it called inflate sequence sorry play but it's async 08 for completion this should in theory allow us to pop as many tiles as we can as long as there are pops on our port okay excuse me let's go inside youtube editor everything has compiled okay let's uh play the game let's see so um let's move this here it pops this and this and this which is perfect it keeps popping but there is a big little problem here that it even wait it pops them even if they have like uh two items only in a what's it called in a connection okay let's go here and as you can see also before we go ahead if there's no matches these swap positions back okay let's close the play mode let's go in writer if connected tiles is less than t skip them okay oh sorry connector tiles let's skip one let's count so if i go here unity again wait for the scripts to recompile let's run the game again and let's move the piggies over here matches these all our three matches okay perfect uh but what if i have only two oh this is my two yeah it doesn't match them if i have only two so as you can see i have three items three items as well okay perfect so as you can see it's working pretty fine and if we have four items okay let's try and match these match those as well match those as well so yeah that's pretty much it for the matching and popping of the tiles now we need to add some sound effects and the scoring so scoring is going to be pretty simple let's go here in the canvas and add a ui element sorry text element let's call it score text let's disable the debug uh inspector let's go align the text to or attach the anchored attacks to the top left corner zero one let's continue align it to the top left here let's set it to auto size align it to the middle center say score equals zero i might want to change the color but i'm going to just keep it white okay uh let's go in writer and let's add a yeah let's go ahead and add a new script call it score counter well you know what let's rename it to just score no no it's called counter which is a little confusing but i'm just going to use it so sealed glass we're going to remove this these new spaces are going to have a public static sorry private static integer called score and a public static mint uh you know what you might want to use the singleton pattern here so let's go ahead public uh static score counter instance let's say get private set just like we did in the port class i'm going to have a private void awake say instance equals this using expression body we are going to have a public integer called a score sorry a private integer and call it first underscore score then we have a public and score which is the property i'm going to say get score and set if the score is not already equal to the value so if it's already equal to the value sorry return uh otherwise set the score to the value we need to reference our score text let's add a serialized field private tmp text mesh pro ugi text this is called text and we're going to go ahead and say score text let's set text use an interpolated string say score equals scored that's pretty much it here let's go back to our port.cs and do one simple thing in the end over here or you know what once the uh deflation sequence is done we're going to increase the score so we go here and say score counter.instance let's score plus equal tile dot value sorry.item but the value times the connectedtiles.count so it's going to give a score depending on how many tiles you just popped and multiply this number of tiles that have just been popped by the value of the item okay let's go in unity everything has compiled perfect let's go to score text disable these add the score counter component and let's go and play the game let's see as you can see we get score but you might have noticed that there were some pics down here that weren't uh popped when we were doing the pop again stuff like this so this is because we go from the top left to the bottom and when we change the like the items on each tile some items might pop up in a new position that can be popped but since they have already passed and uh they were like before our current indices they have skipped we're going to need to reset the loop to go from the top left again all the way to the bottom right to do this simply go to writer and underneath the inflation sequence we reset so we say x equals zero and y equals zero um this is going to happen only if there are matches here so this ensures that if there are pops they will be sorry if there are matches they will be matched and popped okay now let's add some sound effects so let's go here in our board and add a couple of fields first a serialized field private audio clip um collect or pop so i'm gonna just call it collect sound and we have a serialized field here as well we call it let's off type audio source so you can call it audio source no underscores okay and go all the way down here and before the deflation sequence begins i think we should give the score okay and play the sound effect so we're going to say audio source dot play one shot collect sound let's go in unity once the completion is done let's go to the board and add in audio source component let's go inside of it change the 3d zone settings make sure it's 2d disable play and awake let's assign it let's track our collect sound and let's play the game so as you can see there are some matches here that are initially not solved um to do this we might go ahead here and add in the start method we might add pop over here but i don't really prefer this you can go ahead and do some shuffling algorithms it's pretty simple you can shuffle the board until there are no pops possible but for the sake of the tutorial we're going to keep it simple and not do this okay just going to go in unity now and test the game as you can see we play sound effects and we get scored and as long as there are pops available we do pop them okay um so i think i should add that this is this part over here has been added to the video after it has been initially recorded uh i missed that i uh sorry i forgot to add or to prevent swapping tiles from anywhere on the board so i'm going to show you what i mean right now and how to fix it so currently you can swap tiles like this so this can go here which is not really uh what we want we want only adjacent tiles or neighboring tiles to be swappable okay let's close or exit the play mode it's going right there let's go all the way down to pop method sorry all the way up to the select method and check if um selection that contains that no i'm not going to do this we're going to check if the selection is more than zero so if you have already selected a tile uh okay i'm going to read this and we're going to yeah we need to check if we don't already have the style i'm going to check if the selection is more than zero okay i'm going to add some code here so let's add a comment there for now and we're going to say if we have already selected something um do something do the following here otherwise just add this tile to the selection so if the selection is more than zero so if you have selected a tile we're going to check if the other incoming tile is contained within the first tiles neighbors so to do this we check if array dot dot index off which basically returns the index of a specific value inside an array so a rated index of selection okay sorry tile section zero dot neighbors and the incoming tile is not equal to negative one to say selection that add the tile so what this does over here is check if the tile the second tile that we're going to add to the selection is one of the first tiles neighbors otherwise it'll just not do anything so let's move this up like this and make it a single line and let's go back to unity okay um let's play the sorry interplay mode let's go and try moving two things far away it won't work but we can swap neighbors so as you can see this has been an oversight and i have just added this part to the video so please excuse any confusion that this might have cost okay so i think that's pretty much it for the game i hope you enjoyed this tutorial if you really uh if you did please leave a like and consider subscribing check out my assets on the asset store and my games on each dot io and my assets as well on http thank you so much for watching i know this is a long tutorial but hopefully it was useful thank you for watching again and i'll see you in the next one
Info
Channel: Winterbolt Games
Views: 5,026
Rating: undefined out of 5
Keywords: match 3, matching, 2d game, game, 2d, unity, unity engine, how-to, scratch
Id: 9i_sktmLg30
Channel Id: undefined
Length: 80min 41sec (4841 seconds)
Published: Mon May 31 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.