How to make Wordle in Unity (Complete Tutorial) 📚✏️

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello my name is Adam in this video we are going to learn how to make Wordle in unity Wordle is a web-based word game developed by Josh Wardle and owned and published by the New York Times company players have six attempts to guess a five-letter word with feedback given for each guess in the form of colored tiles indicating when letters match or occupy the correct position I realize I am very late to the world Trend but I still thought it would be fun to make a tutorial for this game a lot of people have been asking me to cover more UI stuff so this tutorial will do exactly that if you need help at any point feel free to join our Discord Community where we can offer direct help there is a link in the description of the video please consider subscribing to the channel to support my work we actually just crossed 10 000 subscribers so thank you everyone for that without further Ado enjoy the video let's begin by creating a new project using the unity Hub in the top right corner we can click the new project button from here we can choose a template to start with for this game we don't really it doesn't really matter we're not really going to be using any 2D or 3D components or really just using some of the UI components Unity offers but let's use 2D anyways because it's more of a QD game than it is a 3D game at the very top too we can also choose which version immunity you want to use depending on which versions you have installed for this tutorial I'll be using 2021.3 which is the current long-term support version the most recent long-term support version it doesn't really matter though um once again we're not going to really be using anything special in this tutorial that shouldn't be available in any of the most recent versions so feel free to use whatever you want here let's name our project Wordle or call it whatever you'd like and let's pick a location to save this so I'm just going to save this on my desktop go ahead and create your project and from here it might take a couple minutes to initialize so we'll pick it up as soon as it finishes okay let's start by setting up our game board and actually first I'm going to rename ours the sample scene that uni provides I'm just going to call this Wordle it doesn't actually matter but just to keep things organized here and he left it or a hierarchy where we can see all the game objects that exist in our scene so initially there's just a camera and then on the right is our inspector we can inspect the components and customize the properties of those components for whichever game object you have selected so I'm going to start by actually changing the background color here of our camera if we go to our game view we can preview what that looks like and I'm just going to change the color here to be one two one two one three so I'm going to go with a more dark themed version of the game here um I believe this is the exact same color they use on the New York Times website if you're using the Dark theme but doesn't matter feel free to set that to be anything you want one thing that is important is making sure the projection is set to orthographic it should be set to that already if you use the 2D template if you use the 3D template I think it'll be set to perspective so I would change it to orthographic and then make sure the size is set to 5. but other than that there's nothing else we need to change on our camera we do now need to create a UI canvas everything really is just going to be UI elements so we need to create a canvas to render those UI elements on so we can right click on our hierarchy and go to UI and then select canvas this is actually going to create two different game objects because the canvas it also creates an event system which is used to handle inputs as it relates to the UI systems for our canvas there's a few components there's obviously the canvas itself which tells it where to render how to render um we can render in camera space we can render in World space we're going to just keep it at screen space overlay here I do want to check the Pixel Perfect though it'll just make sure since this is basically an entirely an entire UI game it'd be nice to make sure the UI is as crisp as possible as perfect as it can be so I'm going to check the Pixel Perfect there and for the canvas scaler this is used to scale the UI based on screen size well there's different methods of scaling the screen size one of them being to scale with screen size which is typically what you would want to use especially if you're developing for mobile devices for example you generally want to scale the screen size to sort of match um or to kind of adapt to whatever the screen size is is if you're on mobile there's lots of different screen sizes it's never usually the same whereas on desktop for example it's pretty Universal that people are running on let's say 1920 by 1080. obviously that's not always the case but that's certainly most common whereas on mobile it's pretty it's pretty all over the place so scaling the screen size is usually important just make sure your UI adapts to different devices this really just comes down to what devices you're looking to build the game for and which devices you're going to support um if you're let's say you're developing for tablet and you want the game to be landscape typical resolution in for a landscape tablet device would be 1280 by 720 for example or if you're in portrait mode let's say you're kind of Designing with the intention of people using it in portrait mode you might want to do 720 by 1280 here as a reference resolution the reference resolution kind of serves as like here when you set up all your UI in unity it's you know this is kind of acting as the um as the uh kind of Base size of everything so let's say then you the the game actually runs on a device that's larger than this resolution well then it might you know scale it down a little bit or scale it up as it needs to to try to match the reference resolution as closely as possible now for me since I'm developing this more for desktop and or the web I'm going to set my reference resolution to 1920 by 1080. because that's a more traditional kind of you know desktop resolution and then here there's also a match mode so it's going to prioritize trying to match the width or the height based on this slider here I actually typically try to keep this in the middle to try to match both the width and the height foreign this is where let's say if you're developing for tablet and you're developing you know with the intention of it being a portrait game you know maybe then you want to match the heights um or or the width um because the width might change I don't know this is where it's kind of hard to say there's no one answer you really just have to play around and test it so feel free to adjust these as well as the reference resolution you can also preview your game in different resolutions so that might be a way to you know there's nothing really to see right now since we haven't built any UI but eventually when we have UI you can change this and kind of just see what it looks like under different resolutions with these particular settings or whichever settings you have set up and then finally the graphics the graphic Ray Caster component here is used to detect like button clicks and things like that it raycasts to see if you've actually clicked on a button or interacted with different elements so we we don't we will need this because there will be a couple buttons but um there's nothing we need to customize about it [Music] all right now let's set up our game board by creating some child objects of our canvas so let's right click our canvas and go to create empty I'm just going to call this board for game board I'm going to click this little diagram in the corner here for transform this allows us to Anchor this object to different parts of whatever it's parented to and in this case it's parented to the canvas and our canvas is running in screen space so really this is just anchoring it to let's say the left side is doing or the right side of the screen or the top of the screen or the bottom of the screen I'm actually going to choose this one in the corner this is going to stretch it in both the horizontal and vertical axis and now these um values here become Left Right top bottom rather than positions and widths or width and height the these sort of act as offsets so it's going to offset it by that amount from the left side of the screen or in the right side and the top and so on now so I want this to fully stretch the entire screen so I'm going to set all these to zero so it's going to stretch it all the way to the edges of the Left Right top and bottom with no offset foreign now from here I want to create another child of the board and I'm going to call this a row so our game board is going to have six rows and each row will have five columns one column for each tile before we customize the transform on a row let's actually create a tile so let's right click our row and create another empty object here and let's create a tile or name it tile and actually let me delete that let me back up I'm going to right click the row and I'm going to go to UI and I'm going to create an image actually I'm gonna call this tile the image here will really be what a title will customize all the properties on this but let's just start with this and before we duplicate this because we need five tiles per row I actually want to turn this tile into a prefab that way once I duplicate it I can just customize the one prefab and it'll customize all of the instances of it and I'll have to manually tweak each one individually so let's go to our project panel let's create a new folder for prefabs and I'm going to open that and simply drag this Tile game object into that folder this turns it into a prefab it's a prefabricated game object that we can reuse throughout our entire project and now if I were to customize this prefab it will customize every instance of it in our scene or in our game okay now that we have our prefab set up you can also see it changes to this so now it'd be blue and it has a different um you know different icon and so on I can duplicate duplicate this let's make sure there's five of them I'm just going to call them all tile here now they're all stacked on top of each other which we don't want so if we go to our row we can add a horizontal layout component which is going to automatically lay them out horizontally and from here I do want to add a little bit of spacing between them so I'm going to set the spacing to be for example 16. this might seem like a random number but it's actually fairly common in UI design designers typically design using a numbering system or like a either a grid system or they use um sort of a numbering system so for example they might say a small amount of spacing is four pixels and then a medium amount of spacing is eight pixels and a large amount of spacing is 16 pixels and so on they might use multiples of four multiples of eight or or so on that's pretty common and standard in in UI design so 16 here is actually very um this is pretty common actually which is why I'm using that number doesn't actually matter though so feel free to customize it I do also want to change the alignment here to be middle Center so I want to kind of Center everything now you won't see a change yet because our row itself isn't aligned properly but this will make a difference once we align our rows as well and for the record when we add a horizontal layout group it's it's really positioning the tiles the children of this object not the row itself so this is this components on the row but it's really affecting the children you can actually see when we select one of our tiles it says and they transform some values driven by horizontal layout group so it's really these tiles that are being affected um by our layout group here so we're going to do the same thing on our board which will then affect the rows and then everything will get centered but lastly here on our layout group we actually don't need it to force expand the width or height so we can just uncheck all of those other options [Music] cool so that is our row now that we have a row set up let's also make a prefab out of our row so I'm going to take our row I'm going to drag that into our prefabs folder too and now we can duplicate our row we should have six of these there should really you could have more or less if you wanted but then the standard version of the world game has six rows you you're able to make six guesses um before you win or lose okay so now all of our rows are stacked up on each other so let's go to our board and let's add a vertical layout group all right so now that it's going to automatically lay those out vertically now it aligned them to the top or to the upper left the top left and since our board stretches to fill the entire screen space that's why it's kind of aligned there but we can change this to Middle Center and we don't need these to force expand thee with or the height either but I do want spacing the same amount of spacing I did for our um for our rows so now you can see there's kind of a perfect grid here um now the reason it's still not aligns in the centers because the width of our rows doesn't make sense so the width is set to a hundred but each one of our tiles is [Music] um set to a hundred so really it should be 100 times 5 plus 16 times 4. um maybe that was a little confusing let's see if this works well this might just simplify things we can tell our if we go to our board we can tell the rows to automatically size using the control trial size so this is basically saying the board here is going to automatically size the children which in this case are the rows and so now we don't even need to calculate that number it gets that automatically you can see this is grayed out I can't even change it because it's getting calculated automatically so that simplifies things that's nice everything is centered evenly spaced we have a perfect grid here of components so that's it now in terms of just getting our basic kind of game board setup [Music] next I want to customize the styling of our tiles themselves now since we have a prefab for this if I were to open up this tile here and let's say I change the background color to red as soon as I save this you'll notice all of them change and that's why we wanted to set up a prefab because now I can just customize the one prefab it's going to update the instance of all of them and they all should be the same so it makes sense that they all stem from the same source so for the prefab itself [Music] I want to change the color of these to match the background so I'm going to use the color picker picker here and just set them to be the same color as the background every time I save it'll get updated now of course now we can't see them but it'll make sense in a moment [Music] I want to add a new component here called outline which creates an outline around the image and for this I want to change the color to be sort of a lighter gray so I'm going to use the color 3A root 3A 3a3c and I'm going to make sure it's fully opaque I don't want any transparency on that so you can see that there and let's change the distance here to be three and three here we go that looks good so there's each individual tile kind of styled and once again you know I'm kind of going with a dark theme Here feel free to change it entirely you know if you want to go with a light theme you might you'll probably have your background be white you'll make this this color to be white then you might want to make the outlines more of a like a kind of a light grayish other than um then what I have here so feel free to customize it to your preferences that's it for the basic styling of our tiles of course there's still more we need to do though so we need to create a text component as a child of our tile that way we can actually display a letter in each of these so to do that let's right click our tile here and let's go to UI and there's a few options we could use unity's Legacy components which are frankly easier to use but they're not as robust but for the sake of this since it's more standard these days is to use text mesh Pro um which if you don't have that option if you don't even have the option to do that you can go to your package manager which can be accessed from window package manager and you can check which packages you have installed in your project so I already have text mesh Pro I I believe it should come pre-installed but if it doesn't you can switch this to Unity registry and you can find text mesh Pro in here and you can then instead of if it's not already installed this will be an install button so you can install it that way TexMex Pro is a way more robust text system that is pretty standard to use these days so I would recommend that over unity's old Legacy components so anyways let's go back to our tile prefab let's right click our tile go to UI I'm going to choose text mesh Pro here now since this is the first time I'm using text mesh Pro I need to import all the text mesh Pro assets so I'm just going to click this import TMP Essentials it's going to create a number of new Assets in your project panel here don't need to change anything there that's all fine but now we have our text component I'm just going to rename this simply to be text it doesn't really matter though so you can see that show up of course these will eventually just show a single letter so for example we can do letter G now let's customize this so it fits properly inside the box and do the fonts and everything like that all right so I'm going to do a few things um first I'm going to Center align it and I'm going to vertically middle align it actually I'm not going to middle line it I'm going to actually change this to be midline instead of The Middle it'll make it so the text um for different for the well I guess it might depend on what font you're using but I found that I'm going to change the font we use but um for the font I plan to use I found that if setting it to the middle it visually doesn't look like it's centered in the middle of the tile and I found that midline works actually a bit better but that might you know differ depending on what font you're using so feel free to just kind of play around and see what looks better you can also adjust the sizing of it which we'll do in a second so on the transform here let's anchor this or have well we're gonna have it stretch to fill the entire space of the tile so we're going to go to the stretch mode both horizontally and vertically and I'm going to set all of these to zero so it's going to stretch it to fill the entire space of the tile it's parented to and so now what you could do if none of these alignment options work for your preferences you can also just reposition it using this um numbers here so for example I could offset this by five and it might shift it up a little bit but for my purposes I'll keep all that at zero the other thing I want to do is make sure that whatever we type in here is always uppercase so you can click this uppercase option and this will guarantee that whatever is typed here will always be uppercase okay what else um the font so let's change the font and then the font size so I'm going to import a font um I believe it is called what is it called it's called clear Sans it's actually a fairly common font that's used in UI design um and I think it's one of the fonts that is used on the New York Times website if I'm not mistaken but that font I'm sorry I'm doing some other things on my other monitor real quick um let me just Google real quick get a link for us I know this is a a pretty open source fonts that's [Music] um yeah so here's the GitHub page for it for example developed by Intel it's called clear Sans um it's an open source font so you can download it from here we will want for example the ttf files you can download these um and there's different you know different weights bold Etc I'm just going to download this um I'll have a link to this in the description of the video you can also download my project itself if you want which will also be linked in the description of the video and in which case if you download my entire project it'll already have the fonts in there so you can pull them out that way but also feel free to use your own fonts you don't have to use this font but if you were I'm going to download this so on the GitHub page here I'm just going to download the zip we will extract this I'm just going and extracting this here extract all and let's open this up let's find those ttf files I'm just going to drag all these into my projects although first I'm going to create a new folder for fonts here so I'll open that up let's just drag all these I don't think we need all of these different variants all these different weights but might as well just have them all anyways now from here these fonts don't just work out of the box with text mesh Pro if you're using the other like Legacy Unity text components you can just drag in one of these fonts here but text Pro renders things a little bit differently so we need to convert these fonts to like a text mesh profont I'm going to select all of these in our project panel I'm going to right click go to create text mesh Pro I'm going to do font asset this will generate basically a text Mash Pro font asset for each of those and so now they're they're all named SDF and they have a different icon so that's what we can drag now into the font property here of our text component I'm going to use the Bold one so drag that in there and that looks a little bit better and I'm going to increase the font size as well I'm going to set the font size to say 50. that looks good cool so that's it for the styling of our text now and and now that we have that set up I'm going to clear out the text here we don't need that to say G and that's it okay now we can start scripting our game and we want to handle checking inputs so we can actually type in and set the text within each of our tiles let's go ahead and create a new folder for our Scripts and let's create three scripts there's only going to be three scripts used for our entire game so one's going to be the for the board one will be for a row and one will be for a tile so board row and tile so I'm right clicking create C sharp script for each of these board row tile and let's go ahead and open up our prefabs for let's say let's say our tile here and let's drag our tile script onto that save that open up our row prefab and drag our row script into that save that and then our board we can drag our board script onto the board game object so now we have our scripts assigned to all of our different things we added them to the prefabs that way they get assigned to all the instances of it you can see as I scrub through all of our tiles here they all have this script on it and same thing for our rows let's start with our tile here so our goal is to be able to set the text of each tile when you type so we need to have a reference to our text component and our tile so we can do that I'm going to get rid of all the boilerplate here start fresh now since I'm using text mesh Pro I need to get a reference to the text message Pro text component so I need to import using TM Pro in order to do that if you're not using text mesh Pro uh you'll want to import using unityengine.ui and we're going to actually need that anyway so I'll leave it because the other like the image and outline components are part of the UI system so but let's start with just getting a reference to our text component if you're using text mesh Pro this is going to be text mesh Pro U GUI is the name of the component and this will be a private field here um if you're not using text mesh Pro it's literally just called text in our awake function this is a function Unity calls automatically when the script is first initialized make sure it's capitalized with an a it's case sensitive otherwise Unity won't call it for you we can assign our text component here saying text equals git component and or actually we need to get component in children because our text uh our text component is actually part of a child object of the tile so git component in children and we'll specify the same type here once again if you're using if you're not using text message Pro this will be text and then same thing here text cool so that's establishing our reference to our text component let's also add a public function to set what letter the user or what letter should show up in that tile and we're just going to pass a Char here like a character and this will be the letter we want to set and so here we can say text Dot text I know it's a little confusing but we're accessing our component which is called text and then that component has a property called text which we can assign to be the letter however this is expecting a string not just a Char so we're going to say two string there we also want to store this letter in our tile that way we can access it through our game logic later so let's create a public property um a public Char called letter we're going to specify this has a getter with a private setter so this is a public property well really it's a public getter and a private setter um that's kind of what the syntax is doing it's it's a c-sharp property that actually creates a hidden the old underneath you know we're on the hood it creates a field and it kind of sets up your get arm private Setter automatically for that hidden field uh when we call this function we want to assign that property so this dot letter equals letter we need to use the this keyword here to distinguish this because they're named the exact same thing so you you could name this differently but um this is going to refer to the property it this is referring to the instance of our class and so this dot letter is referring to this property up here whereas here is just referring to the parameter cool so that's it for now in terms of our tile component let's go to our or our tile script let's go to our row script our row script and all we need for our row is to keep a an array of tiles so let's do a public array of tiles we're gonna do the same thing here we're going to make this a public editor with a private setter because we need to be able to access these tiles from our board script so we want to access this but we don't want anything other than the road to be able to actually assign what these tiles are in our awake function make sure it's capitalized we'll say tiles equals get components so plural make sure it's plural with an s in children and then tile cool so that's it for now that's all we need to do for our row script at least for now and finally in our Boris grip we can start writing the logic to handle um key presses so normally speaking um normally speaking in Unity when you're looking to detect inputs you do that in the update function so since this is already provided I'll keep this here I'll explicitly Define it as private it already is implicitly private but I like to explicitly type that out so typically or what you would normally do is say if inputs dot get key down get the I can't type I mistyped that okay let's try that again get key down or get key up for example um you would use those to check let's say key code dot a you know if you want to detect if you press you know your a key that's what we need to do however we need to check the entire alphabet we need to check multiple keys so we need to kind of loop through an array of keys and check each one so first let's define that array now that array is always going to be the exact same it's never going to change so we can make it a constant although C sharp we can't actually create a constant array but we can create a static read-only array and this will be an array of key codes we'll call this supported Keys typically constants are capitalized like this that's why I'm doing that technically this isn't a constant but for our purposes it's basically a constant let's create our new array here and now we basically just need to say key code.a key code.b comma key code.c comma key code.d Etc we're going to kind of go through the entire alphabet purely for the sake of time I'm just going to copy this over from my other projects because you don't need to sit here and watch me just tediously type all that out but yeah type it all out type each key code out a b c d all the way through Z make sure there's a comma after each one and make sure there's a semicolon at the very end after your last curly brace or your closing curly brace make sure you put a semicolon there um so let me copy this over again cool so we got all of our keys A through Z those are the only letters or key codes we want to support we don't need numbers we don't need you know commas periods or anything like that just the letters themselves and now we can Loop through this array and check each one so for ins I equals zero I is less than supported Keys dot length I plus plus if inputs dot get key down on access that the key at that index if that has been pressed down well then we need to set the letter for the tile we're on now we don't know which tile we're on right now so that's what we need to handle next is we need to keep track of which tile we're we're at let's define two private fields for our row index and our column index type there we go row index column index these will default to zero so zero zero would be this first one then zero one zero two zero three zero four one zero one one one two one three one four Etc they're indexes so there's they start at zero rather than one now we do need to get an array of our rows just like our row has an array of tiles our Board needs an array of rows so let's define an array of rows here and in our awake function we will assign that rows equals get components plural in children and now finally we can now we can access that so we can say for example rows row index dot tiles column index dot set letter and we can specify a letter here so we can save a for example um now we need to convert whichever key this is to a Char to a character which Unity actually supports out of the box so we can copy this here and we just need to cast it to a chart so we put parentheses and fronts and inside there we put oops inside there we put char so this is something Unity supports automatically so we have to explicitly cast it to a Char but we're good there we can set the ladder now once you've set the letter for that tile we need to advance to the next column so we can set the next tile so we're simply going to say column index plus plus that just increments it by one and lastly if we've detected that you've pressed an input um we need to break out of our for Loop we don't want to check for we don't want the user to press multiple Keys within the exact same frame the game is running so they can only press one key per frame um and then the next frame it'll pick it up again this actually will prevent a bug that I noticed when I first developed the game if you spammed your keys really heavily and you you basically pressed multiple Keys within the exact same frame is possible to run into a situation where the indexes get a little messed up so we don't want don't want that so we're going to break out of our for loop after we've detected a key down and that's I think it at least for now let's go ahead and test this out and yeah Adobe assign our scripts I think we did so yeah our row has row script how has yeah everything has all the scripts board has the board script let's go ahead and run this and hello there we go so I've typed in hello I can't backspace yet so we'll handle backspacing next now there is one error here so if I type in another key I'm gonna get an error so if I go to my console here let's just type in a letter boom I get an index out of rainix range exception so our column got incremented but there's no actual tile for that new column so we get an index out of bounds error so to handle that we need to we need to only Loop through these keys if you're you know not out of bounds so we can say if column index [Music] um is less than or really I'll set this up for when we handle backspacing so if column index is greater than or equal to um however many tiles are in our current row so our current row dot tile is that length or here we want to handle backspacing which we'll get to next um backspacing I can't type there we go so we'll handle backspacing here this is saying if you're if it if you're out of bounds we want to allow the user a backspace um well I well I guess actually we want to be able to backspace anytime so that's not even accurate um what this actually should be is not backspacing but if you're out of bounds we want to check if the user submits the uh row so once they've typed in a full word here they can press enter to submit that row so we'll get to that eventually so let's actually this is not backspacing that was inaccurate this should actually be like you know submitting a row which we'll come back to else so if we are in bounds then we can Loop through all of our keys and check for that so we're going to just move this for Loop inside inside our L statement here so if we're out of bounds check if we submit a row else if we're not out of bounds well then we can of course handle keys all right so let's test this just to make sure I don't get this error again even if I spam Keys Beyond um V bounce so I'm spamming I'm spamming keys right now and yeah no error pops up so we'll get there we fixed that problem all right let's handle backspacing it should be pretty straightforward in our board strips we want to add a new we want to handle backspacing first and foremost before we do any of these other things so we can say if input dot get key down key code.backspace then we will handle that and then we're going to change this to an else if so this becomes now one big conditional block if we backspace we'll handle that else if they're outside of the balance then we need to handle submitting a row which we'll get to later else they're inbounds they haven't backspaced then we can just do our normal um checking for our normal Keys our normal inputs so for backspacing here we need to set the letter again so basically the same line of code but instead of the key here this will just be hard coded to um forward slash zero this is basically a null null uh a null character for when you're typing in characters versus strings characters or chars use single quotes whereas strings use double quotes that's sort of the distinction between those so single quotes and then um forward slash zero is basically a null character um and that's it for now there will eventually be more things we do in here but that's good for now now as something I something that just helped this code out in general all of this is I want to store what the current row is that way I don't have to access you know you'll see the same bit here you can see I'm using it three places I'm gonna end up doing this several more more times I'm just gonna pull this out into a variable here called current row so the current row will be rows at whatever row index we're at and now I'm going to replace these with current Row in those three spots so just makes the code a little bit more readable current row.tiles set letter current row.tile settler Etc oh and then I guess I forgot one thing once we backspace we need to decrement the column index we need to decrease it by one now it's not unfortunately it's not as simple as just saying column index minus minus because then we could get into negative values which we don't want so we're going to clamp this within um within the right bounds so we could do that but that doesn't work instead we could say column index um oh and the other thing is we actually need to do this first because when you backspace here let me let me run this right I'll so I can demonstrate this better let me comment that that here okay so may run this all right so let's say I said hi right now I if I were to backspace I want to delete the I but we're technically on this third right now the index that we're at is this third column we're at this third column so if I I don't want to clear out the third column which is their columns already empty I want to actually clear out the one before it so we need to decrease the column first and then we'll set the letter but once again we don't want to just do minus minus because then we'll get into negative values so I want to say or I can say column index equals math F that clamp column index minus one and I'm going to clamp it between 0 and however many tiles there are five I could have hard got five but it would be better to say would be better to say current row.tiles dot length however we don't even need to clamp it on on this end because you you only ever going backwards in directions you this will never even matter so instead we can actually do a Max function we'll say column index minus one and zero so what this is doing is it's going to get the maximum between these two values so it's going to evaluate this and zero here and it's going to pick whichever the two is greater what this is doing is so let's say our column index became negative one which well that's that's what we're trying to avoid well zero is greater than negative one so we would end up assigning our index to zero so this is basically a way of clamping it just on one Bound in this case the lower bound you could do the same thing to clamp on the upper bound using a Min function and if you actually took a look at how a clamp function is implemented a clamp function is just both a Max and a Min sort of combined together that's all a clamp really is so max clamps on the lower bound and a Min clamps on the upper bound and a clamp actually just does both together in one function call but anyways cool make sure our index here doesn't go out of bounds we do that first and then we set the tile um of that column to a null character so I should be able to say hello backspace and clear it out and once it's fully cleared I can still press backspace without getting any error cool all right so I can just kind of type so there we go that all looks good next we need to check when we submit a row we need to check for the input to submit a row once you've typed in an entire um word so let's go to our board here we already kind of put a placeholder here so I'm just going to replace this placeholder with if inputs dot get key down key code dot returns that's your Enter key um then we will submit that row now let's um let's create a function to handle all that logic so let's say submit row and we're going to actually pass in the row that we're submitting so here then when we call us we'll say submit row current row now for the logic of actually submitting a row before we can do that we need to do a couple other things we need one to pick a word we need to compare what you've typed into the actual answer so we need to pick an answer which will be random and it will pick a random word from a dictionary and then we can compare your guesses to that and we also need to set up our tile States so that the tiles would change colors based on if you are correct or not so we can't we need to come back to this um but let's focus now on just loading the data I'm simply loading the dictionary of words we'll we'll use Wordle actually has a like set list of allowed words um and there's actually two sets of two lists of words uh there's a list of words that can be an answer and then there's an additional list of words that you're allowed to guess and the list of words you can guess I think I think they refer to those as like the supported words they're the supporting words think there's like 12 000 words or something like that whereas there there's only like two to three thousand words that can actually be the answer so I actually have those saved as text files um in the GitHub repo so in the description of the video there will be a GitHub link to the repo here and if you go to assets resources there will be two text files here ignore the meta files that's just what Unity generates but there's official Wordle all and official Wordle common so we need to save these two files here um I'm gonna click on the all here yeah it looks like for all there's 12 972 so these are all of the words that you are allowed to actually enter into the game I'm gonna click raw here which just use the raw text file I'm gonna just right click in here and do save as I'm Gonna Save this to um to my project so I saved this project on my desktop so I'm going to open up my project I'm going to go to assets let's actually create a folder called resources we explicitly needed to be called resources I'll explain why in a second but let's save that text file in there and then let's do the same thing for the um for the common one as well so resources official word all common so there's 2 315 words that are acceptable uh answers like actual words that it'll pick from so let's view raw and let's save this to that same location as a text file cool now you can if you want write your own files too so here now in unity that resources folder showed up I have those two text files so feel free to you know if you're totally welcome to create your own list of words if you want um but if you want to use the official words from the game then here are text files with every single one in there now the way if you do write your own list make sure that you have each word on their own line um yeah basically each word and then enter new word enter word enter word enter make sure there's no additional characters at the end you know there's no Extra Spaces or anything um there's just the five letters enter five letters enter five letters enter Etc um that'll be important because we need to parse out we need to parse that text file to extract all the words from it so if if yours is formatted differently then your code is going to look different you could for example have like a a comma delimited list um something like that which but it'll just your code would just look different in order to parse that so um so anyways cool let's actually load these words now now the reason why we need that to be in a folder called resources is this is a special folder that Unity has that allows us to load these assets at run time if it's they're placed in a different folder then we won't be able to load these at runtime essentially when you build your game Unity takes anything in the resources folder and includes that in your bundle which then allows us to load it dynamically at runtime if it's not um if it's not in resources then we can't load it so anyways let's go ahead and do this so we need to keep an array of two arrays one for the solutions and then one for all the supporting words or I'll call them valid words valid word so the solutions are what we'll actually pick from so you'll pick a random solution that will then compare against when you guess but your guesses themselves can be any of the valid words when we start so let's add a function called starts when our script first starts so this is called by unity automatically the very first frame your script is running make sure once again it's capitalized or it won't get called in here we can say load data which will be our own function so load data we're going to eventually do other things and start that's why I'm separating this out into its own function but here for loading data the way we do this is to say resources.load and then we just simply specify the name of that file it already knows automatically to look in this folder so we just need to specify the name of the file so resources load this will be official Wordle all and then when it loads it just loads as a generic Unity object but we want to specifically load this as a text asset um and then we want to assign this to something so um we'll say text assets I'm just going to call this text file equals resources.load this file as a text asset and now once we have that text file we can parse it to assign our solution so all here um or all here is actually the valid words uh so I'll do that one valid words equals text file dot text so that's just getting the entire string of text in that file dot split this allows us to split it into an array of strings using a some separator here and that separator is going to be a new line um so we'll say a new line character here so that that's actually it that's all we have to do to parse it which makes it simple sir like let's say you had a comma separated list um which is a actually a pretty standard format I think it's I could see CVS CSV yes CSV Commerce comma separated values and a pretty common file format in that case you would want to split it by a comma instead but in our case they're kind of separated by new lines so we're going to split it by new line now we're going to do the exact same thing for our um our Solutions as well the only thing that'll change here is this will be World common and we've already defined a variable with that same exact name so we'll just reassign it we don't need to redeclare it we just need to reassign it foreign that's all we have to do for loading that data Let's test that that works by itself before we move on even those are private arrays if we switch to debug mode if we switch to the debug mode and unity we can still see those so here yeah we've got our Solutions yeah so it's loading all those correctly and we've got our valid words as well [Music] cool so that is loading those that data set correctly foreign data loaded we want to pick a random solution word that we can compare against when we submit our row so let's store what that word is um I'm just going to Simply call that word and um let's see where should we do this let's create a few functions there let's create a function called set random word and for now I'll just call this and start uh eventually this will get moved to like a new game function but for now this is good it's a set random word so how do we pick a random well it's pretty straightforward um since we have an array we've already parsed out an array all we simply do is say word equals um uh Solutions and then we need to access an index and we'll just pick a random index so we'll say random.range between zero and however many solutions there are there are so between zero and the amount of items in our array and that's it and this is inclusive exclusive so this works already for arrays we don't have to worry about it being out of bounds if you're using floats it will be inclusive inclusive but if you're using integers it will be inclusive exclusive now one thing we should do just as a sort of a safety precaution is we should lower case the word and trim it trim it just removes any Extra Spaces that might exist in the front or back we want to make sure it's lowercase though because when we when these Keys get converted to characters they'll they'll be lowercase and so when we have actually compare it we want to make sure everything's all lowercase when I say word equals word dot two lower and I'm gonna say dot trim so we're lowercasing it and trimming any additional spaces that might exist there shouldn't be any spaces but just in case um we'll do that so now let's test this let's run this and we should see let's go to our board script here debug this and yeah so we got a random word magma if I were to run again this will change to Belch and Etc it'll be random every time labor cool okay let's handle the logic for submitting a row and comparing it against the solution word we're going to actually start with this simple version of the logic um and later we're going to revisit that logic with some of the ID the edge cases the simple logic is well quite simple and there's really not much to it um but to properly handle the edge cases it gets kind of complicated so I want to just start with some simple um with just simple solution so we can test more of our game out and actually you know handle doing the tile States and things like that and then we'll come back later to do the full set of logic for submitting a row so just bear in mind what we're about to write here is going to change is actually going to change somewhat drastically um later in the tutorial so just when we submit a row we basically just need to compare every tile in the row to every letter in the word so let's start by looping through all of the tiles in our row so for INT I equals zero I is less than rho dot tiles.length I plus plus and we need to compare each letter of the tiles to each letter in the word so if um well and first let me store what the tile is so row.tiles I so that's the title we're currently in in our Loop oops let me delete that if tile.letter equals word I so this is accessing our string it's accessing the character at this index in our string so if those two are exactly the same if the letter that we stored in our tile is the exact same um character in our word at that same index of that same position then that's a perfect match so this is correct now we don't have the tile States yet but this will be you know the correct state if it's not correct then it's either wrong entirely or it's just in the wrong position so let's handle if it's in the wrong position um if it's we know it's in the wrong position if the word contains that letter but it but it wasn't an exact match like this so we can just say if word that contains that letter well now we know that letter is at least in the word it's just in the incorrect um or just in the wrong spot and if neither of those is the case then it's not in the word at all and it's just completely incorrect that letter is not correct in any way so that's it that's the entire basic logic for Wordle once again this doesn't cover all of the edge cases and this will get way more complicated um but I'm going to start with this just so we can advance to checking our tile States and so on um now one thing we do need to do is once you've submitted your row we need to advance to the next row so at the very end of our um for loop after our for Loop we'll say row index plus plus and then we need to reset our column index back to zero so we're advancing to the next row and then restarting at the beginning um if you've gone if you've exceeded to the past all the rows well then you've lost at that point and we don't want to allow the user to do anything anymore so we can just disable our script which will prevent update from running so we can say if our row index is greater than equal to however many rows there are rows.length well you've exhausted all of your guesses you've lost and we'll just disable our script we'll we'll come back to that as well what you know we'll we'll set up some UI so you can try again and so on but for now let's just disable it so you don't get any errors it'll when the script is disabled update will not be called foreign cool that's it for this let's test this out obviously we're not going to get the feedback to know if if what we typed in is correct or not but we can at least see that advances to the next row and then I can type in again um yeah so there we go I was able to type in a word press enter type in another word for Center type in another WordPress enter and so on so that's all good so now that we're handling submitting a row with some basic logic we need to actually provide the feedback to the user if they were correct or not um to do that we need to add different tile States we need to kind of set the color um of our images and outline and such based on the state let's go to our tile script here and I'm going to declare a struct inside here or not a struct actually um just for a specific reason I'm going to call this um I'm going to declare another class within our tile I'm going to call this state normally speaking I would make these things trucks um but there's a particular reason why I don't want to do that in this case and that's because at some point we're gonna write some logic to say you know if the tile States equals a correct state um yeah I don't let me explain that later once we eventually get to that but trust me when I say that we'll want to make this a class for now in our state here these are just going to have colors to indicate um you know the tile so we wanted to define a color for the fill like the fill color and the outline color and those basically map to [Music] um you know those basically just map to the let me get out of debug mode map to the image and the outline so fill color is for the image and the outline almost for the outline color [Music] cool next let's go back here so we have our state [Music] um we need to store what state the tile is currently in in the same way that we're storing what letter that is currently saved in your tile so it's basically do the same thing here we're gonna say state state this will be a public getter with a private center and we'll create a public function to set the state so we're passing in the state the state we want to set and when we set that state we need to update those colors on our components so we need to get a reference to our image component and our outline component and this is where we needed to import using uni nginet UI and we'll get a reference to each of those so private image I'm going to call this the fill in a private outline I'll call that outline I'm going to rearrange this I'm going to move these all the properties up top it doesn't matter but I like to have those up top first and then those cool so in our set State we want to store what that state is in our class so we need to say this dot State again so we can distinguish between the parameter and this property despite them having the same name and now we can update our color so um fill dot color equals state DOT fill color and outline dot color it's actually outlined at effect color is the name of the property um equal state DOT outline color so that's setting those colors based on the states now for the states themselves we're going to declare those in the board because they should be the same for the entire game we don't really need to declare the states themselves in the tile because then we would have to set the states for every tile but they should be consistent in the same for the entire game so I think it actually makes more sense to declare those in our board script um one sort of neat thing you can do in unity is ADD headers um and I'll call this States for example I'll show you what this looks like so let's declare a state here I'm going to call this let's start with um well I'm going to say public tile.state let's call this empty state actually I'll just add all of them now so we have our empty State we have an occupied state so that empty is like what you're seeing now an occupied State means there's a letter there but that's it you don't know if it's correct or not yet you just know that it's occupied by a by a letter occupied state then there will be a state for if it's cracked or not that's where it shows up green there'll be a state for if it's in the wrong spot that's when it shows up yellow and there will be a state for when it's incorrect and that will show up basically grayed out so those are our five different states now when we look in the editor you're actually not going to see anything nothing happens and that's because we need to see serialize our class here so we can add an attribute above this say system.serializable that allows um you need to know how to show that data in the editor now so boom now it shows up and we get all of these here and that header so you I added this little header here that also shows like a little label label in the editor too you don't need to do that it just helps you to maybe organize things if you have a bunch of different properties on a class and maybe organize them sort of group them together like that and I did that intentionally because later on we're going to add a different set of references to things and so it would be just as kind of nice to us because we'll separate those into two different groups anyways let's actually assign these states so this is where you know feel free to customize this based on your preferences but I'm going to set these two um the colors used by the the times or the New York Times version of the game once again I'm doing sort of a dark a dark themed game here so for the fill color of the empty State this will be it's actually the same as the background color so I'll just use the Color Picker there make sure the elf was set to 100 the outline yeah I mean the the empty stay is literally what you're seeing now so we already defined these colors earlier 3A 3a3c make sure the alpha is a hundred um the fill color for the occupied State doesn't change that'll also be the same background color I'm gonna update the alpha the outline color when it's occupied will become a little bit brighter so it won't be as dark as this it'll be a little bit different um so this is five six five five seven eights I believe let me double check that five six five no no that wasn't quite right five six five seven five eight there we go change the alpha so it's a little bit lighter than than the empty one the correct state is the one that shows up green so that is this color here 538 d4e and this will be the same for both the fill and the outline so same exact for the wrong spot this will be a yellow color b59 f3b once again you don't have to use these exact same colors I'm using you feel free to customize them same thing fill and outline will be exactly the same and lastly If it's incorrect it's going to be this outline color but both for the fill and the outline make sure you've set the alpha on all of these to 100 right I guess you don't have to but make sure they're at zero or you won't see anything cool so we've set all of our colors finally let's add the last few remaining lines of code here so here now we can say tile that set state to the correct state which we declared here and then same thing tile set State wrong spot state tile set State um incorrect state and then we should also set the empty States while the empty States we don't need to set initially they're already initially set to the empty States um so we'll use that when we eventually clear the board to retry again but we do want to set them to be occupied so when whenever we set the letter here but we do want to say current row of tiles column index set state to be the occupied state um oh and actually I I was wrong we do need to set the empty State now which is when you backspace so when you backspace we'll say column index set empty State there we go cool let's um yeah let's test this so now we should be able to see that this is working and at this point we almost have a basically a working version of the game it's not quite right but it's pretty much there I'm going to cheat a little bit and see what the word is so the word is Moody so let's just type in let's just type in hello oh I'm getting an error so something's wrong um oh that's because we forgot to assign our references here to our fill in our outline if I missed something here we need to say fill equals get component image an outline equals get component outline here we go forgot to do that okay let's try that again [Music] rerun I'm going to cheat again so the word is phone I'm going to start by typing in hello so H is highly yellow because there is an H in the word it's just in the wrong spot same thing with e there's an e but it's in the wrong spot and same thing with o um there's an oh but it's in the wrong spot and there's no L's so those get um you know trade out let's type in the word guess so there we go so there is an e but it's in the wrong spot what about games same thing now let's type in a word that starts with p um place there you go so we got the p and the E are both in the same are in the correct spot so those show up as green and if we were to type in the entire word we would get phone and the whole thing turns green so that point you would have won the only thing I haven't tested is if you type in it's kind of hard it might be hard to see but when you type in a word you can see the outline changes a little bit it becomes a little bit brighter and then when I backspace it goes back to the empty state so that all looks good so everything is working there with our tile States let's go ahead and revisit some of the logic for determining if a tile is correct or not we're going to handle some of those edge cases so for the sake of visualizing this let me just hard code the word here to um games you don't need to do this in your project but I just want to demonstrate this Edge case real quick so if we run this and let's say I type in guess oops yes so the problem with this is with the fact that there's multiple s's in my guess literally but there's only one s in the actual solution where the S at the end is correct but there's another s that indicates that it exists it's just in the wrong spot and this is confusing because there's only one s so really it should highlight the correct s ense since you've um guessed that but the other s shouldn't even be highlighted at all it should actually just indicate that that's completely wrong since you've already found the 1s that occurs so basically this Edge case just has to do with the number of recurrences of letters if you have more than one occurrence of the same letter you run into situations like this that are confusing to the player if I were the player here I would assume there's actually two s's and then I would start to guess my words based on that but that's not correct so how can we handle this let's go back to our board script I'm going to remove that edge case or that hard-coded word now and we need to kind of refactor our logic here the problem is we can't just simply check if the word contains the letter because maybe the word has already um maybe it contains it multiple times and you've already guessed it or the word only contains it once but your guess has um that same letter multiple times and if you've already gotten it correct then it should only highlight one of the two um so in other words if you enter in a word that has multiple of the same letter but the solution word only has one of that letter it should only mark one of those two as either cracked or wrong spot or whatever it shouldn't Mark both of them so we need to write a system that will sort of almost in a way factor in the number of occurrences of a word and there's probably a few different ways we could write this let me show you how I've sort of come up with a solution for it now the first thing is I'm going to comment this outward that's kind of the old Simple Solution we're going to basically rewrite all this the first thing that I found to do is we need to we need to kind of do this in two phases first we need to just check um all the correct positions and then we'll check separately as a different for Loop we will check if things are in the wrong spot um so first we have two for Loops one check if things are correct or completely incorrect like it doesn't even exist in the word at all after that we'll have a second for Loop to only check the remaining letters to see if they're in the wrong spot the important thing here is we need to keep track of the word but we're going to remove the letters from the word once they've been uncovered in a sense if if they've been marked as correct we're going to remove that letter from the word and then when later when we check the wrong spots we're only going to look at the remaining part of the word that hasn't already been checked this will remove the case where you know multiple letters are getting highlighted when there should only be one of them being highlighted so let's create a copy of our word by just defining a new variable and assigning it to our word so that's going to be remaining and we're going to update this as we um reveal things so let's set up our for Loop just like we were before I is less than row.tiles length I plus plus let's get a reference to the current tile row.tiles I and we're going to start with the same logic here of checking if it's the correct um correct letter in the correct position so this won't change if tile.letter equals word I well we know that that is correct so we can mark the state we can set the state as the correct state but now we want to remove that letter from our remaining um string here so we can say remaining equals remaining dot remove the way this function works is you provide an index so that's I that's our index we're currently at and you can provide a count so how many characters do you want to remove starting at that index and we're just removing one one character now um we still need to keep our string at the same length so we actually need to add back a character but we're just going to insert instead we're going to insert at that same index in empty space we we need to make sure our string is is not changing length or it's going to cause some index problems later on so basically we're replacing that character that we just indicated is correct with just an empty blank space really this could be anything um anything that's not a normal letter I suppose okay so now that's one thing oh we can also check here if um if it's incorrect so that we know it's incorrect if the word doesn't even contain the ladder at all so we're going to basically do this line of code but we're going to do not if it does not contain it so else if our word does not contain the letter child letter well then we know it's completely Incorrect and we can just set the state to be incorrect and we don't need to update our it doesn't even matter about updating our remaining word in this case okay so now separately we're going to have a different for Loop so that's kind of our first pass through everything we're going to go through the through it once just to indicate cracked and correct now we're going to go through it a second time where we're comparing against the remaining word just for the wrong spots so set up our for Loop the same way let's get a reference to the tile and first we only need to apply this logic if the tile has not already been if the tile state has not already been set so we can say if the tile state does not equal the correct state and the tiles state does not equal the incorrect State those are the two states we identified up here so if it's neither of those then we know okay that means it must be um in the wrong spot and this is also where a while back I mentioned we wanted to make our state a class rather than a struct a lot of times you would maybe Define this as a struct but in this case I want it to be a class because um here as I in order for this equality check to work it's comparing it based on references it's doing it's a reference a reference of quality essentially in this case or well that's not so like kind of misspoke there it's doing object equality it's saying well this object is the exact same as this object these are the two same things they're both referencing this exact same thing in memory um if this was a struct I mean I can even show you it'll give me a warning or I believe it should should give me an error saying yeah these things aren't even it doesn't know how to compare these things I would have to manually conform my struct to be equatable um you can you can add the equatable uh interface you can conform to that which requires a whole bunch of things to then compare the different properties so checkouts are equal I don't care about any of that and it just complicates things so all I care about is hey has the state been set to the same instance that I'm providing here and is if those two object references are the exact same then yeah I know then I know it's correct um so that's maybe that made no sense to you but that's why this is a class rather than a struct not that it necessarily matters anyways anyways I digress so we know it's not the correct State it's not the incorrect state which implies it's the wrong State or the wrong position state or I think I call it the wrong yeah wrong spot state we need to now check that the remaining word um the remaining word contains that letter if the remaining word contains the letter then we know yeah there is actually a second instance of that letter that is in the wrong spot so if the remaining contains it the tile letter then it is actually in the wrong spot if the remaining does not contain it then we also know it's actually just a duplicated instance of the same letter but there isn't in the solution where there isn't multiple instances of that ladder so it's actually just wrong so we'll just mark it as wrong here tile set state to incorrect state here will be tile set state to the wrong spots did and we still need to update our remaining string here as well in case maybe there's a third instance or fourth instance which is pretty Edge case but it's still possible to happen um now the thing is we don't want to um so here let me change this again so let's say we just copy this exact code here in theory that's what we want the problem is this index isn't the correct index because the um the tile or the letters in the wrong spot it's the wrong index so we actually need to figure out what the correct index is before we update this remaining string so we're going to just say remaining that index of the letter that'll give us what the correct index is supposed to be and that's where we'll update that and replace that with um just an empty space here so that's it for solving our edge cases I know this is maybe a little complicated a little bit more confusing especially if you compare all of this code to just this this is way simpler way easier to understand just a few basic conditions but unfortunately that just doesn't hold up for how the game should work this should cover all of the different edge cases at least the ones that I've run across I don't I I haven't run across any other cases that don't work but please let me know if you do um so let's retest this let me reset the word more re-hard code the word here to um games and now if I type in a word that has two s's it should only highlight one of them so let's try this so I'm going to type in guess yeah so now this time the one that's correct gets highlighted the other one doesn't even get highlighted it just says nope that's incorrect entirely which I think makes sense because once again the solution order only has one s so it's confusing if it were to highlight the second S as being either incorrect or is being in the wrong spot let's try a different example as well let's say the solution word is um place and let's say I type in the word hello [Music] so same thing here it's going to find the first instance of L so it finds the first out says oh that was in the wrong spot the second time the L shows up well there's not a second l so it doesn't even highlight that one at all so that's another good example and what about if we flip-flop these so what if the solution word was hello and we typed in place what would happen there I don't even know if this is an edge case at this point but let's just see what happens solution war is hello and we type in place so yeah in this case I mean it kind of works as expected cool um what about if we type in a word that has um let's just this won't be a real word but let's just type in three of the same letter um so one of them this is why it's important that we separate our for Loops into two separate for Loops where we first do a pass-through of what's correct and then we do a second pass of what's in the wrong spot this first the green one here will get highlighted first and then it does a second Loop to say okay well let me go back through again and see what's in the wrong spot and this is where well there's two there's two other L's that it could choose from for the second L and hello but it's just gonna do the first one it finds but this will tell the user hey okay well there actually is two L's in the solution one of them is correct one's already in the correct spot there is a second one it's just in the wrong spot and then the third one was that there isn't Three L's in the solution word cool so that is that so that's kind of solving our edge cases which is pretty important for this kind of game next up let's test if you have typed in an invalid word so wordle's a game where you're not supposed to be able to just type in random letters you actually need to guess a real word otherwise it's not valid let's see what I if I play the game here what did I get I got oh yeah I still have it hard coded I need to remove that line of code but let's stick with hello I could just type in random letters um you know a b c d e f whatever okay cool I found that e is one of them now I can continue I can say f g h i you know J okay I got now I got h k l m n o okay cool p q r s t right um uvw x y and at this point I could start to kind of piece together now this one is actually maybe still not solvable because there's a two L's which kind of throws it off but in a lot of cases this would tell you okay well I know what the five letters are and I just kind of scramble those and find what the word is so you're not supposed to just type in letters like this so how we how can we account for that well that's what the second array is that we loaded is a valid word so you should only be able to type in valid words so when we submit the row before we do anything we need to verify the the word you've typed in is a valid word otherwise we don't even allow the submission of it so let's create a second function just to say um if a word is valid so this is going to be a function that returns a Boolean true or false you're going to pass in a word here and we will determine if that word is valid the way we do this is by looping through our array of valid words and if it finds it in the array then it is valid otherwise it's not so for n i equals zero I is less than valid words that length I plus plus if valid words I equals the word word comparing then yes we can return true we know that's a valid word if it ends up looping through oh sorry let me re fix that just type that return true there we go if we end up looping through the entire array and we haven't returned true well then that must mean we never found it in the array and therefore we can return false it is not a valid word so finally when we submit a row at the very top of our function here we want to check that first if this is not a valid word then we will do something we're going to do some stuff and we're going to return we're going to exit out of the function before it executes any of the other logic now the problem is we need to pass in the word that I've typed in but they don't type in just a string they type in individual characters individual letters so we need to form the word from those letters this is where it's probably useful to have a helper property in our row that can kind of form the word for us so why don't we declare a public property that's a string called word this is just going to have a getter so we're going to kind of Define a custom getter here that's going to piece together all the letters of each tile and form a word we'll start with an empty string we'll Loop through each of the tiles in our array and we'll concact these together so word plus equals tiles I dot letter then finally we'll return our word so we're just contacting all of the letters together to form the complete word and now we can pass that in here so we're testing if the word or that row is valid if it's not then we will do something in exit out of this function so what should we do when it's not valid well we should show some kind of text or something to indicate to the user that hey this isn't valid we need to provide that feedback to the user so let's go ahead and add some new a new text object to our canvas here I'm going to right click our canvas and go to UI I'm going to create a new text component once again if you're not using text mesh Pro you can use the normal Legacy or old Legacy components that's fine however you want to form a text component I'm going to call this um invalid word and I'm just going to Simply call this um or stuff a text to be invalid word I'm going to update the font here actually I'll do the font last I'm going to Center align this so I'm going to also middle align it I'm just um have it not wrap I'm going to disable wrapping and I'm going to Anchor this to the bottom of the screen I'm going to have it sort of show up towards the bottom of the board so in our diagram here I'm going to Anchor it to the bottom here the bottom middle and when we do that now if we set the Y position to zero it'll be anchored um to the bottom and actually I probably shouldn't middle align this I guess it doesn't matter but I could you know bottom or top line yeah it doesn't really matter so I'll keep that um but nonetheless I want to raise this up so I want to offset this from that bottom so it's anchored to the bottom but I don't want to be literally at the bottom so I want to offset this bag a little bit let's just say I increase it or offset it by 100 pixels um and for following like a numbering system like I mentioned before maybe we offset it by like 124 or something would be a multiple of eight there were actually 120 AIDS is multiple of eight cool so invalid word let's adjust the color and kind of styling of this a little bit more so I'm just going to change the color I'm going to use the same color as the like outline here I think it's the same color five six five um foreign five six five seven five eight no that's not right I mistyped that it's five five six five seven five eight there we go it's like a light gray I'm gonna decrease the font size a little bit and I'm gonna change the font to clear Sans I'm gonna do the medium weight yeah that looks good and I think I'm gonna uppercase this as well so feel free to kind of customize how you want this to look there's no right or wrong way to do this but I think that looks good kind of just up here there at the bottom and indicate to the user that this is invalid now I'm going to deactivate this object initially because I don't want it to show up when the game starts so I have completely turned off the uh that's um that game object but I need to reference it now in our script and then show it when you get an invalid word so this is where I'm going to create a new header here just for like UI references you don't have to do that just helps organize the different properties in the editor I'm going to well actually first we need to import or using TM Pro since we need to get a reference to that text mesh Pro component if you're not using TM Pro or text mesh Pro you'll want to import using Unity engine.ui here if you're using text message Pro you'll say text smash Pro view GUI or if you're not using texture codes just simply text I'm going to call this the invalid word text cool so let me also delete this hard-coded word to hello we don't need that anymore so here I'm going to show that so I'm going to say invalid word text oh you know what the thing is um I guess it's fine we don't even need to reference this as a text mesh Pro yugoo we could just reference it as a game object for Simplicity um but it doesn't necessarily matter but in either case I'm going to say dot gameobject dot set active to true so we're going to show that text when your word is invalid um and then we need to hide that text again once you've backspaced once you've sort of cleared that invalid word out then we can hide it again I'm just going to do the same exact line of code except it'll be set active to false and that should be all we need all right so let's run this [Music] and let's go ahead and just type in some junk letters oh I got an error actually and that's because I've never assigned my reference to that component so here in our board script I never assigned this reference let's go ahead and drag that in and let's try again foreign ers invalid word cool now let's say I type in hello that is a word that shows up in our text file so once again it's looking at all the words that show up in this official Wordle all I think we can even open this up and let's find the word hello yeah so there we go we have the word hello in there so you it's possible you might actually come across some words that are real words but they're not supported by Wordle Wordle doesn't consider them for the sake of the game Wordle doesn't consider them as um words and once again feel free to customize this list if you want to cool place so on yes um what's like what's an example of a word that might not work even though it is a real word I think there's a lot of words that if you just do like a plural version of it it doesn't work um I I can't even think of something anyways it doesn't matter but that is how we can support uh invalid words let me just test this one more time much water is invalid I backspace and it goes away cool sweet so all we have left to do now is basically provide the player a way to restart if they lose as well as detect if they win or lose um and then also to maybe pick a new word so they can continue to play again basically just gotta complete the loop so they can play again and actually Chuck the win state so let's go ahead and set up a couple buttons at the bottom as well that we can show whenever the game ends so I'm going to right click our canvas I'm going to create a button this time using text mesh Pro so button text mesh Pro if you're not using text mesh Pro you can use the Legacy button components which will then use a legacy text component set up our button here there's a lot of ways you can customize button Styles so I'm going to Anchor this to the bottom middle just like I did for the invalid text I'm going to probably use that same offset 128 I'm going to increase the height of my button I want to make them a little bit bigger and I'm going to make it there's gonna be two buttons side by side so I'm going to make them be exactly half um kind of take up half but still have 16 spacing in between so if our board I believe let's see how how big was one of these rows our rows were five six four so five six four but there's also going to be I don't know 16 spacing in between them and then divide by two that's what I want the width our of each button to be so 274. um and then if that's the case I need to um offset it one to the left and one to the right but first let's go ahead and update some of the other styles as well so let's see I'm gonna change the background color to be the same as the background of our scene I'm going to add an outline just like I did for the tiles I'm going to move this up here it doesn't matter though I'm going to set this to be the same as our tile outline I believe this should be three a three a three C to make this a little bit thicker three three let's see what else um well let's make sure the opacity is fully there we're going to change the button text color to be um [Music] the same as that invalid word text so that's five six five I would this is the one I always forget five six five six five seven five eight cool I'm going to increase the font size of our button text a little bit I'm going to change the font itself use Clear Sans I'm going to use regular and I'll use medium on this one [Music] um this is where it visually doesn't feel like it's aligned in the middle so I'm going to use midline here that just visually it looks a little bit better to me I'm also going to upper case it just kind of stick with that styling for everything I'm going to disable wrapping and then this one let's say this is the new word button so maybe when you win it'll prompt the button to say you know basically play again but choose a new word this time um and what else is there anything else I want to do here um over the button itself when you hover over it and you click down there's different states I don't really care about any of those States so I'm actually going to just set the transition to none and eventually we'll hook up the function that happens when you click on it but we'll get we'll come to that we have to write that function in our code first before we can do that so I think that's good I think this stylistically looks good to me um I guess so I can remove the Sprite from the image here because it the defaults right actually has slightly rounded corners and I want to just make them Square so I can just delete that and now it's kind of perfectly Square that all looks good let's go ahead and duplicate this button because we want two of them side by side and I ended as sort of off um kind of I need to um offset them one to the left one to the right what I can do here is change the pivot of one of them to zero and change the pivot of another to one [Music] um and then this if you calculate it out this should be 282 I believe that is half of the half of the width of um a row so five six four divided by 2 is 282. so 282 for one and negative 282 for the other and there we go so now we've got two buttons that are equally spaced um perfectly kind of line up with the edges for this other button this is going to be maybe try again don't have one button that's try again so we'll call that that we'll say try again button and we'll call this one new word button actually I'm going to rename this to invalid word text there we go so try gun button new word button so those will show up whenever the game ends if you get a game over maybe you want to just pick a new word maybe you want to try try again using that same word um and then same thing when you win you can click new word to play again with a new word or I know for whatever reason maybe you want to play again with the same with the same word maybe you want to try different guesses even though you had one maybe you want to try guesses to see if you can still find a different solution so anyways that's good for the setup let's go ahead and go back to our board script and get references to those two buttons so here we can reference these as buttons and um if you do reference uses buttons you do need to import using UD engine.ui once again we don't actually need to reference these as buttons because all we're going to be doing is showing and hiding them so you could just reference them as game objects but in either case let's say this is new word button and this is the try again button so before we can show and hide those we need to actually determine if the user has one or not so let's add a function to check if they have one so return Boolean true or false has one and in here we just need a loop over the current row you're on um and if that well let's kind of do the same thing we did here where we'll pass in a row so it'll check if that particular row is has one basically um if that row matches if all of the um states of the tiles are correct then you know we've won so we can Loop over each tile for into I equals zero I is less than row dot isles.length I plus plus if uh row.tiles I does not equal the correct State then we know they've not won yet otherwise if they Loop through the entire thing and we've never returned false then that must mean all the tiles are in the correct State therefore we can return true oh and this should be tiles I dot state my fault there so as your function to determine if you've won or not we should call this function towards the bottom after we we submit a row it goes and it updates all the states of everything at that point we should check if they've won so if has one using that row let's disable in the same way that we disable the script when you lose or where did we did we do that somewhere enabled oh yeah right here so at this point you've exhausted all of your guesses so we disable the script that way the user can perform any more inputs same thing when you win too we also want to disable disable the um the game when you win that way they can't input anything until you play again foreign and so with that in mind whenever the script gets disabled we should show those two buttons and whatever the script is enabled we should hide them so Unity has a way to do this automatically we can just add a function on enable and on disable so these are built-in functions that Unity will call automatically assuming they're case sensitive like I've typed them here and we can just say try again button Set uh that game object set active to true and same thing for our uh what was it new game or new word button yeah or and actually this should be the opposite so when the script is enabled you're playing the game in which case we don't want to see these anymore and when you disable the script that means the game has ended in either a win or a loss in which case we want to show this cool let's just test that really quick and then we'll hook up what happens when you actually click on the buttons and then that will be a completed version of world so let's just make a bunch of guesses here oh I got well I got an error already ends because it's like I always do I forgot to assign the preferences to these so let's dragging these references and also I should deactivate these initially just like we did for our invalid word text let's play the game Okay cool so let's just say I type in place place place place place place place I've exhausted all my guesses and then the word the buttons pop up now the other scenario is that I get it correct so let's check that that happens I'm just gonna cheat and look at what the word is so I got the word whack I'll at least put one wrong guess in there and let's type in the word whack so there it's fully cracked and boom the buttons show up you can see the script got disabled and the buttons showed up I'm not able to type anymore because the script is disabled now we just need to hook up these buttons so when you click on them it actually restarts and then we're done that's the entire game of world so let's go back to our script one last time and we just need to write two functions really we should write a new game function and a try again function really um I'm gonna make these public because we need to be able to hook up our buttons to these functions so they need to be public to do that so I'm going to say new game as well as try again whenever you do a new game we're going to um set a random word and re-enable the scripts and if you try again we're not going to set a random word we're just going to re-enable the script but we also need to clear the board in both cases too so we don't have a function for that and now here when we start we could just say new game but we need to clear the board we don't have a function for clearing the board so let me go ahead and write a function to clear the board clear board basically it's just looping through every row and every tile and setting the letters back to a null character and setting the stage to the empty state um cool so for inch um we actually have to have a two Loops inside of each other here so I'm going to say for INT row equals um zero row is less than rows.length row plus plus and then here or ins column equals zero column is less than R whatever the current row is dot tiles that length column plus plus and then finally we can say rows row dot tiles column dot set letter we're going to set it to be the null character again so that's a forward single quotes for character and then forward slash zero for that is a null character and we're also going to reset the state too so rows dot tiles column dot set state to the empty state foreign X and column index so row index equals zero column index equals zero now we just call this function from each of these so whenever you start a new game we'll clear the board and choose a new random word re -enable our script if you try again same thing we're just not going to set a random word we'll still clear the board we'll re-enable it but we don't set up random words that's the only difference between these is whether you set a random word or not and that's it we're done um I think let's try oh well we still gotta hook up those buttons but that's really easy so let's go ahead and hook up those buttons and give this a try so in our buttons here there's an on click field here we can click the plus sign and then we can drag in a reference to our board here I've seen people in the past Dragon um references to the script itself don't do that that doesn't provide you anything to choose from you want to drag a reference to the game object that contains that script and then we can go and click the script and choose which function you want to call so which one this is for the try again button so let's do board try again same thing for the other button we'll drag in our game object we'll choose that script and we'll select new game for this one that's it alright let's play it so let's start with in me losing I'm just going to type the same thing over and over again so we've lost now here let's test both scenarios um so what is the word the word is gloats I'm going to click try again this should stay the same but my row and columns should reset obviously everything should get cleared away there goes everything got cleared the word is still the same row and column got reset please please please please please please please please now if I choose a new word everything should clear but I got a different word so I got fishy let's actually type in um [Music] uh let's actually make a correct guess I'm just really typing fishy everything shows up I can try again if I want to it probably aren't going to try again if you've won but who knows same thing I could type in fish you can maybe maybe you want to try again even though you got cracked because maybe you want to try a different you know see if you can get it again but using completely different words I think that could actually be kind of fun um but in their case let's also do new word word changes everything resets we're good now well that's a quite a play I know the word place is a pretty common initial guess for Wordle um so I already know what the ending word is but considering I got four of the five letters off of the first guess this would probably be a pretty easy one to win on had I not already seen what the what the word was but anyways that is a completed implementation of Wordle I really appreciate you watching this tutorial and I hope you learned a thing or two along the way give the video a thumbs up or down to let me know how I did subscribe to the channel for more videos just like this one and leave a comment recommending what you would like to see next if you want to support my work even more you can become a patreon member to receive exclusive benefits including access to the unity assets that I develop Link in the description of the video thank you for watching see you in the next one foreign [Music]
Info
Channel: Zigurous
Views: 32,873
Rating: undefined out of 5
Keywords: unity tutorial, unity, how to use unity for beginners, how to make a game, unity 2d tutorial, game development, how to make a game in unity, unity 3d, unity 2d, game dev
Id: Tbcgqz5lM38
Channel Id: undefined
Length: 117min 4sec (7024 seconds)
Published: Tue Nov 29 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.