16844 words on this page!
Project Brief
The first lesson of the clicker game was finding out how to use the UI within Unity. We learnt that the first thing that you need to add is a canvas since that defines whether the UI is displayed on top of the player's camera (Screen Space) or if it is displayed at a certain place in the 3D world (World Space). Screen UI is usually the HUD for your game so how much health you have, as well as ammo, what you have equipped etc. This is displayed in the same place regardless of where your camera moves. On the other hand, you have the world UI which is a piece of UI that is displayed at a certain place within the world that you create. If you do damage to a monster in a game, it might show some text saying that you dealt a certain amount of damage. However, the main difference is that if you look away from it, it won't stay on your screen since you aren't looking at it.
As you can see here below, I made two canvases for some UI to start with. On the left, there is the screen space UI which I have put a health bar and ammo count on. On the right, I have made a world space UI which shows some simple text that says you have dealt some damage. If I move the camera outside the range, the text will no longer be displayed.
Inside of the canvas, I did need to add some other things though to make things appear on the screen. The first element you'd usually add is a panel. This is the red shape of the health bar and the blue shape for the ammo count. I then added a text element within these and resized them to fit nicely and that's what I have. I did pretty much the same for the world space UI.
Here, I positioned the camera in a way so I could demonstrate how world space UI is seen. As you can see, I have the camera selected and you can kind of tell where the maximum reach of the display is. If I move the camera so it no longer has the text within it, it starts to disappear from the view.
Close to the World Space UI
Further away from the World Space
In this lesson, we added some text to spice up the game more. I kept everything from the other time, but this time, I got some fonts to make it look better. We used dafont.com to find and download fonts to use. Once downloaded, I had to extract the zipped folder and then I could drag and drop the font file into the project. To use it, I then just selected it in the menu and it works. In this instance, I used the legacy text within Unity since I don't need any crazy effects yet, and you need a specific font file to be able to use it as a TMP text. I downloaded the Super Cartoon font for the main text on the health bar and ammo bar. I then also downloaded Starborn which gave me the star icons as the letter a, which you can see at the top right.
Next, we were taught how to add images. For this, you simply add an image element within the canvas. You can then drag and drop the image you are going to use within your assets, before selecting it and changing some settings to make it sprite. I first set the Texture Type to be Sprite (2D and UI) to make it compatible with UI. I then set the Sprite Mode to Single, before setting the Compression to None, since this can sometimes make the image blurry. After changing these three settings, the image is ready to use and you can drag the image into the Source Image on the Image element within your canvas.
Finally, this is what I have after this lesson. I further redesigned the UI a bit more so that you have the stars up the top right and the ammo count top left. The health is at the bottom left with something that is meant to resemble a character profile just above. I also added an overlay to make it look like you are holding this gun.
In this lesson, we began learning C# code again, but this time within Unity, using the Unity Namespace. However, to begin, we started by adding some buttons to the scene that we would be able to interact with. I added 3, one to shoot, one to reload, and one to keep track of how many times you shoot. I also added a cube which for the moment, I just placed in the right spot in front of the camera to make it seem like an object you can shoot.
Upon creating a button element, you will see that you can make something happen when you click it. This is very useful and can be used to make things happen with or without code. One thing I made happen was every time the shoot button was pressed, it hid the cube. Reload makes it reappear. I would later go on to add a particle effect which followed a similar path. At the start of this lesson, it was important that we made an empty game object and put any scripts on there since then we can access them by using that game object and selecting the script we want to use from the dropdown menu.
Here is the code that I made for the shot count. I had to make sure I added the Unity UI Namespace at the top, otherwise, I wouldn't have the commands for the user interface. First off, I made sure to add two new variables. One of them is a simple integer value which we have already used before. The other is a Unity Text variable, similar to that of Rigidbody. I gave the Text variable the name text, and the integer variable the name score, as well as setting it to 0. Setting the Text variable to nothing means that I can add a specific value to it within Unity, rather than already giving it one. I probably could've removed the Start() void since I didn't put anything in it, but I did add some code into the Update() void, which runs every frame. Here, I selected the text variable that I created, and within that, basically located the text part of it. Without doing this, Unity would not know what part I would want to edit, so I have to define which part, in this case, it's the text. I then set the text to whatever the score is, but since it's an integer, I have to convert it to string data. Lastly, I created a new method called AddScore(). This simply adds one to the score variable, which will happen whenever a button is pressed since I will configure the script to run whenever the button is pressed.
For this lesson about our clicker game, we learnt about adding audio to our game in three different ways: playing it on startup, playing it with buttons, or playing it with code. I used the website Freesound to get all the audio that I used today, and this will probably be the most used place for audio that I need. I could also use a YouTube video converter to get audio, as well as Soundsnap. However, Freesound is what I used this lesson, and what I'll primarily be using in the future.
First, we have to play it on startup. When you add an audio source to your scene, add the audio you want to the audio resource, and select the box Play On Awake. This will play this audio as soon as you click play on your game. I also added a Loop so that it will play again when it ends. This is the simplest way to get background music in your game.
As you can see, I have another audio source in my scene with a different sound this time. This is going to be used for making a sound every time I click the SHOOT button. Since I don't want it just playing constantly, I deselected Play On Awake, as well as Loop, since I only wanted this to play once when a button was pressed. Once I had this audio source modified to my liking, I went to the configuration menu for the button and dragged the audio source to be the used object. I then selected Play() from the AudioSource menu, so it would play the sound when the button was clicked. I also went and did these same few steps for the reload, giving it it's own sound.
Here I have an audio source selected so you can better understand how they work. At this volume, it only reaches this far. As you can see, I also have the camera placed just below, so it will get audio at pretty much the maximum since it's at the centre. This ball around the audio source acts as the distance the audio played can be heard. If the listener (camera) is outside this region, then it won't hear the audio. The further to the edge that the listener goes, the quieter the audio gets.
Due to needing the audio to be at the same volume every time the player presses a button, I moved the audio sources inside the camera so they became children of it. This makes it so that whenever I move the camera, the audio sources move with it.
Here, I made a script for the background music. What this does is it makes the spacebar work as a play/pause function. It also gives me the methods used to play and pause the audio, which I can use with buttons too.
Going into more detail, the script uses the default UnityEngine Namespace. Within the class, I create three variables: audio source, audio listener and audio clip. The audio source is the source of music that I'll be using. This is especially important since it makes the physical sound radius area which is found within the scene. This is what can be adjusted to change the volume, doppler effect, and more. Next, is the audio listener. This is what will be able to hear the audio, such as a camera. It's a simple variable and just requires one listener so Unity knows what is going to be hearing the sound that plays. I assume that you don't exactly need to add an audio listener in unless it's audio that you only want the player to hear. Background music is a good example of this since every player is probably going to want to have something different. However, if you play an FPS game, shots need to be heard by every player, so I guess you just wouldn't need to add an audio listener. The audio clip is the final variable that I define in this script. I make this an array so I can add multiple audio resources. This means that I don't have to add any audio to the audio source, since every audio file can be added into this array, and just automatically be put into the audio source when it needs to be played. I defined each of these variables with very simple names for ease of use and swiftness when making code. I haven't assigned them anything yet since I'll do that inside of Unity. Just below that, I also added a little bool variable which I called isPaused, so the code can keep track of whether it's running or not.
Next, I begin to add some code to the Update method which runs every frame the Unity project is updated. In this, I add an if statement. For this if statement to become true, it requires an input from a key being pressed down. That key must have the keycode of the spacebar. When this becomes true, it goes to another if statement that starts by making sure the isPaused boolean is true. If that is the case, then the Play method is run. If that isn't the case, then the Pause method is run.
Moving down to the final two methods, I started by adding the Play method. This would first of all select the audio source. It would then use the UnPause function to unpause the audio. It then sets the isPaused boolean to false, since it is no longer paused. The Pause method just below does the opposite of the Play method. Instead of using the UnPause function, it uses the Pause function within the audio source to stop the audio. It also sets the boolean to true. I used these specific functions since using Play and Stop will do different things. These can be used if you want to start the audio from the beginning. There are functions for every part, so you can change the volume, loop audio, and more.
This is my second version of the script. After all of the functions worked the first time I made it, I decided to alter the code a bit more to make it better and add a random track method which I could implement into the game. Everything for the first few lines stayed the same, however, in the spacebar if statement, I just made it so that as long as it was pressed, it then goes over to the PlayPause method, which decides whether the audio needs pausing or unpausing. I then got rid of the Play() and Pause() methods and replaced them with the superior PlayPause() method. This works by first opening an if statement that checks if the isPaused boolean is true or false. If it's true, then it will unpause the audio and set the boolean to false. If it's false, then it will pause the audio and set the boolean to true. This just looks a little better in code, cutting down lines, and allows me to have one button to play/pause the audio instead of two.
Lastly, I also added the RandomTrack method which chooses one track at random to change the currently playing song to. This is useful since a lot of the time, players might not want to listen to a certain song and therefore would want to skip it, which this allows them to do. First of all, it stops the currently playing audio. Next, I added the PlayOneShot function, which is used when playing audio from the array. Inside I had to define which array I was going to be taking audio from, and what track I wanted to specifically play. Because I wanted it to be random, I wrote Random.Range, which will choose a random value from whatever you set. I wanted the range to be from 0 to 2 since I had three tracks and they start being listed at 0. However, for some reason, I was unable to use (0, 2) as the range. Whenever I tried this, it only played two audios. Whenever I changed it to (1, 3), it also only played two audios. Although (0, 3) isn't technically correct, it doesn't seem to cause any errors, and each audio plays. So I assigned the method to a button on my UI, and it worked. The next thing I would want to change for it is the way that it can play the same audio you are listening to again. This isn't ideal since if you're pressing this button, you don't want to listen to the audio, so restarting it and having to press the button a second time is mildly annoying, but it'll do for now.
To finish off the lesson on audio, here is what the script's variables look like inside of Unity. As you can see, I assigned the audio source that I called Background Sound. I also set the listener as the Main Camera. I assume since I set a listener, it still means it has to be within the region, so I have also put this audio source as a child inside the camera. Lastly, I have the small array of audio resources. I just downloaded some audio that was long enough for some background music, and was a decent audio for it.
The particle effects are something I've already incorporated into my game, however, we went through them in a bit more detail which allows me to make some things better, such as the bullet which I can now make travel a certain trajectory every time. We went through all the original settings that I found out myself, but then the additional ones below give you even more, in-depth settings which help you get desired results with particles.
This is one of the important settings which allows me to only have one particle sent every time it's pressed, and then changing the Max Particles above allows me to have multiple shown at once.
After learning all of the necessary things that I need to know to be able to start forming a clicker game, I chose to create a new project, this time inside of a 2D Unity project since this makes more sense for a simple game such as this. Because it would be primarily something you could download on your phone, I thought I would make it in this shape. However, I later realised that I could've done it landscape for a phone, which would give me a better-looking game if I was to make it available on PC too. But, this is good enough for my first proper game.
To start off and at least give me a baseplate for ideas, I just called the game Super Clickers. I was unsure of what I wanted the theme and game to be based around, so I thought if I just started making something simple, an idea might come to mind, or this could just be good enough. For the text, I made this cool looking 3D illusion by just duplicating the text and sizing the back one down. I then made the colour darker, for a shadow look. I made a simple play button which I would use to hide the start-up screen and put you into the game.
As you can see in this hierarchy, I only have a few assets for the moment. I have the main camera which will just have the UIs displayed on, and is what the player will use to see when playing. The Start Screen canvas is what holds everything that I want on this screen. I will later add more canvases and they should all look similar to this.
I have also started adjusting the button and made it so that when it's clicked, the Start Screen canvas SetActive state will be set to false, basically hiding it. I will then make another canvas state set to true which will just change the screen shown to the player.
After doing a bit more on the game, I decided to change the original start-up screen so that the background is blue and the text is green, making it look a little better. I then made some more background colours, one being black for the settings, and the other green for the main clicker screen.
I made it so that when the PLAY button is pressed, the starting screen is hidden, and the main (green) screen is shown. I then made a couple more buttons that allowed you to go to and from the settings menu from there. I think so far, the game is looking decent, and I'm wondering how it's going to turn out by the end.
After leaving the clicker game for a few days, when I came back to it I thought of an amazing idea: what if I made a clicker game themed around Minecraft! The main thing that sparked this idea was probably because I was thinking of the name for things you get for clicking and I had inventory value. I then thought I could base it on Minecraft, which is perfect since it's a game that has so many assets that I can easily grasp and use.
Once I had my choice solidified, I thought that the best place to start was going to be the settings menu since I could make the background dirt which is already a great Minecraft reference since the settings menu in the game has a dirt background. To do this, I swiftly loaded up Photoshop and grabbed a dirt texture that I found online. I sized it up just enough so that I could fit in a certain amount in a line, and began copying and pasting the image. Once I had the image which was the right size for the background, I dragged it into Unity and applied the sprite image settings that it required, and replaced the old background image with this nice new one.
Next, it was time to make some buttons for the game. The nice thing about basing it around Minecraft is that every asset for the game is easy to either replicate or just get from somewhere on the internet. The best website that I've found for tons of Minecraft assets is McIcons. It is a great website that has every block, item, and mob as well as some structures and backgrounds - I knew this was going to be the perfect way to get everything for this project.
To start, I grabbed a button from the UI page. Unfortunately, I couldn't find the long button, so I had to do a bit of editing to get a long one. It wasn't too difficult since I just had to cut off both sides to get the full length, and then I got rid of either side for the end pieces. There were some very obvious lines going down the button however from where I had put the pieces together, so I used the smudge tool a bit to blend it together. I think overall, I'm very happy with how it turned out.
Here is what the main square button looks like. I was also going to use this as a little button for things like the settings menu, so I thought I should export this as one too. I also made a clicked button by just changing the outline to white. This is once again just like Minecraft, and gives the user more immersion and helps them to know when something is clicked. I did the same for the long button later on too.
I then went back onto dafont.com to download a Minecraft font, and boom, I have a Minecraft themed play button on my start screen. I did the same thing as before with the shadow, by just making another text layer and puting it behind it. I would later realise that this looked wrong and realise the correct place to put the shadow.
When I had finished the button, I went back onto McIcons and found this really nice-looking background that they had on there. I decided to make a quick little animation which would slowly move from one side of the picture to the other, similar to how Minecraft has a panoramic background on its title screen. This is also where I found the name of the game - Mineclickers. I just took the original Mine from Minecraft, and I chose clickers instead of craft because it's a clicker game and they at least both begin with a c, so I thought it was an ideal game name.
Back onto the main screen, I got a spruce planks background from McIcons and then I started on the actual clicker part. I first made a button which is the background part of the dirt block. I made a shadow around this too to make it look a little better, and added the dirt image over the top of this. I thought this looked great and I tested the clicker just to make sure it worked as intended, and it did. I also thought of making the dark block background change to a lighter colour when clicked, so that was a nice feature to make sure you knew when you clicked.
To finalise this day of production, I added a hanging sign from the game which acted as a drop-down menu which I animated. I included these arrow buttons which allow you to move the sign upwards and downwards. The bundle image was going to be an inventory feature, however, I will probably later go on to remove this until I have an actual use for it, for now, I will struggle to implement a working inventory feature, especially since I have no idea what I want this to be like. It could be something that I use if I were to add separate things that you can do like exploring structures and fighting mobs, however, this will take a lot of time and effort to put into the game, so it might be something I continue to do after I hand in this project. I also added the settings button here with a neat, Minecraft-styled cog as the image.
Before jumping in and continuing to make my game, I thought this was a good point to begin doing some research for the game.
The first thing I did was search for Minecraft Clicker Games online. This gave me various 2D games that people had made in the Minecraft style. The first game that I found and began playing was MineClicker. This is a game that can be found either online or on the Play Store. I played it for a little bit and thought that it was a good game that had a cool concept. Another cool thing was that when I came back to it another time, the game saved my progress, so I wasn't starting from the beginning again. In this game, you click mobs until you kill them, and after a certain about of kills, you can upgrade and get a more difficult one. There are also the blocks which act similar, but you are breaking them. There are two currency variables within this game. One is experience orbs which you gather from killing mobs. The other is a stone or some type of material that you get from breaking blocks. You can hire NPCs with XP, and they basically act as auto-clickers. You can then buy upgrades for yourself which increase the amount of damage per hit on mobs or the amount of damage per click to blocks. You can see the damage stats at the top of the page, which helps you to know what kind of damage for blocks and mobs that you and the auto-clickers do. It would've been nice to know easily which one is the player and which one is the auto-clicker, but you can sort of tell since it changes whenever you buy certain upgrades. One nice feature is that whenever you kill a mob, it drops an XP orb and you collect it. A similar thing plays for the block break. This is a neat feature that I will hopefully do something similar to since it immerses you into the game more, and it's a Minecraft mechanic.
Inside the settings menu, there are a few buttons to click. Firstly, there is a force save button. I'm not entirely sure what it does, but I assume it saves your progress. The SFX button allows you to toggle the sound effects that you have in the game. This includes the mob noises, as well as block breaks. Finally, there is a Reset button, which allows you to reset your progress and start the game from the beginning again. At the bottom left of the screen, there's a button letting you know it's available on the Google Play Store, as well as version text which lets you know what version you are currently playing on.
Overall, this game doesn't have the best-looking UI, however, I like the 3D environment and the transitions to and from the mob and block. The auto-clickers are also a nice feature, and it's something that you can basically buy infinite of, which could be good for the long term. The annoying thing with this is, the name is pretty much the same as what I've already got. I wanted to call my game MineClickers, this game's name is MineClicker, so I'm going to have to think of another name. Going back to gameplay, I might try to take some inspiration from the mob killing if I plan to add more content into the game at some point.
The next game that I found online is called GrindCraft. In this game, you start off with nothing but the oak log in the overworld. You can tap it, and after a certain amount of time, you gather one log. From this, you can craft items just like in Minecraft. First, you'd want to buy planks, then some sticks, and finally you can begin making tools. Once you have a pickaxe, you unlock the mine, where you can mine for cobblestone and other minerals. I didn't dive into the game that much, but you can buy villagers and it seems that you can make a village. This is a cool idea, and maybe this requires you to have purchased buildings before you can get villagers. There are also some achievements that you can get, which is a cool implemented feature that Minecraft also has, so it only really makes sense that a game like this has them. You can also apparently travel to other worlds to get more resources and villagers. This game aims to build a sort of civilisation inside of your own universe, and you do that by gathering multiple materials to craft different things and build more.
Inside of the settings, there is a lot of things that you can do. Firstly, you can check the version that you are playing on. Next, you can adjust the music and sound effects volume. After that, you can adjust the particle amount. This was one of the features that I found to be quite interesting since it's very unique, and it works quite well. The main thing that I thing could be useful with this setting and the sound ones is that it may have an example so you know roughly what it'll look like, but the main thing is that it works. The next page allows you to choose how the display looks. By default, the amount of everything you own is shown as a number at the bottom of the icon. However, you can set it so the inventory and crafting menus are separate. This makes it so everything you can buy is made into a less wide window and the inventory is just to the side. Although it's a neat feature, it doesn't quite work perfectly since it appears to repeat the logs and cobblestone for me in multiple spots. After that page, you can choose to delete your game save. There is then a page right next to that where you can save your game progress. It saves this as a .json file and you can then load it whenever you want to play again. This is a nice feature since you can bring the game save over to a different device and still have the same amount of progress. The last tab in the settings menu is a language button where you can change the language in which the game is in. This is a cool feature which must have been difficult to implement but is useful, especially for making the game available to a wider audience.
Back to the main screen, there is a pause button which simply pauses the whole game. I'm unsure as to when this could be useful, but it's still a cool feature nonetheless. The other button, which has a picture of a monitor, is for setting the game to full-screen. A small feature, but one that is useful for making the game look good, no matter the device and specifications that you have. The game works surprisingly well depending on what way you hold your phone too. If you hold it vertically, it changes the UI to fit the screen properly. If you hold it horizontally, it looks more like what it does on a computer, and the full-screen button also works on this.
This is a really well-made game with a lot of gameplay within it. I love the crafting aspect which really makes the game feel like Minecraft in 2D. Furthermore, achievements would be something really cool to include in my game, and they could give you rewards, giving players more reasons to continue playing. Moreover, having different Grinds is useful for separating gameplay mechanics, but keeps the game enjoyable, especially since there are multiple things happening at once, keeping you engaged. Also, this game has a second game made, called GrindCraft 2. It seems to only be available on Google Play and Apple Store, however, it is a lot more developed with plenty more features, so it'll certainly be something to check out and get ideas from before making my game too much more advanced.
The final bit of research I did for my clicker game was on the one and only Cookie Clicker. I did this on the browser version, however, it is available on Steam to install. Straight away, one of the things that stands out to me is the fact that you can name your bakery whatever you like, and adding a save function in a simple string of text is an incredibly efficient way of doing it, and enables anyone to share their save statuses with each other. Of course, the main saving I want is an automatic one, but this adds an extra step of security which is very important to keep players engaged since someone would be very distraught if they logged on to find their data gone and unrecoverable. Furthermore, this game has an incredibly long possible gameplay loop, which could theoretically go on forever. It doesn't just stop at the main screen we all know. You can also ascend and I guess unlock perks. There is so much packed inside this game that I don't even know about, which is what separates it from the rest of the clicker games. This isn't a simple project that only took a few months to make. This has taken years of development, as shown by the version number and its well-known history. When the game was first made, it sparked an interest in new players and game developers as it started an uprising of a new generation of games - idle clicker games.
One of the greatest parts of Cookie Clicker is the fact that you can buy multiple upgrades. Games that are similar to this include Adventure Capitalist and Idle Miner Tycoon which are games that also have a large variety of upgrades. However, I believe that Cookie Clicker is significantly superior to them since you see the upgrades. Do they all have cool animations that you see? No, but it's just cool to see what you buy instead of just having to trust the game has actually registered that you bought something.
Cookie Clicker also has a cheats menu which is cool and quite unique. You have to input saysopensesame in the name of your bakery to show a hidden debug menu which is quite common for games to have to allow developers to test the game easily without having to go and complete things which could take ages. Furthermore, the debug menu is just fun to play around with, and it has so many functions which further drops hints to the sheer amount of content that can be found within the game. Achievements are another thing that makes this game stand out. There are so many things that you can get and this gives some hardcore gamers a challenge to try and complete the game fully by getting every achievement. Although this takes a lot of time, it's what sets games apart from others. I can't really talk much more about features within this game simply because of the extremely large amount, but there are so many things that I could try to implement into a game of my own that I will definitely be using as ideas.
Back at home, I began streaming myself making the game even better by once again changing the name, but this time for good. ClickCraft still included a segment of the original Minecraft name but had a nice ring to it since both words begin with c and are similar sounding in the way that you pronounce them. Furthermore, I couldn't really use Mineclickers since there was already a Minecraft clicker game called Mineclicker, which would've been too similar.
Because I was at home and had some other programs with great tools inside, I decided to make some proper Minecraft-styled titles for the game. I made these using a program called BlockBench which is a really useful program for primarily making 3D Minecraft models that you can put into resource packs and use within the game. However, one of their plugins is a Minecraft Title Text Generator which is great for quickly generating titles by adjusting some settings, rendering it and then saving it as an image. Although you can do it inside of Adobe's Photoshop and Illustrator, I think it looks perfectly good enough for what I want here, and it would take significantly longer since I would have to do a lot more, so this way makes the most sense to me.
Lastly, I added a little tip down the bottom of the screen to just tell the player that they have to press the Play button to start the game. At the moment, I have everything just appear at once on the screen, however, if I have time to add easing in animations closer to the end of the project, I will, since I could easily animate it, and setting it to PlayOnAwake but not loop would mean that I could have a nice looking start-up animations.
Next up, I added some more to the main clicker screen. I first made a few more titles that I could use throughout the game, one being this one which I just kept as the game's name since I couldn't really name this screen anything specific.
I also added this text box area which I imagined would be an ideal place to display how much currency you have in the game. I used this since it's Minecraft's text area that you would usually input text into I do believe, so it only makes since to have this as the place that tells you whatever score you currently have. This was another UI element that I got from McIcons, and I just put some text here with a background. For now, it's just a #, but it will change when the game starts and I have code which changes it to be the same as the current score count.
The first script that I added in my game was a way of adding clicks to your score. I just wanted to get this working before even thinking of upgrades, so I had something that worked and I at least had the clicker made. Since until now, I didn't really have a clicker game because you couldn't click. This code is very simple, as all I do is declare two public Text variables that act as the front piece of text, and the back (the shadow). I then made a public float variable that I called score, and set the value to 0. I didn't really need the = 0 part since this doesn't change it when it's public since you change the value inside of Unity. Below this, I set the two Text variables to the score variable in the Update void. This means that it will constantly be changing, eliminating it missing changing when you change the score at some point. I made sure to add .ToString() on the end since the score variable is a float which is a number with decimals. Without doing this, I'd get an error since I cannot change the text part in the Text variables since I'm trying to do it with a different bit of data.
Below this, I just declared a new method that I called AddScore(), which simply adds 1 to the score. I can then assign this void to the button to make it add one to the score on each button press.
The next part of the clicker game that I wanted to add was a few settings for the background music. For this, I made a script which I can use again for any settings that I want to edit, but for now, I just needed the music to play. I started out by adding two public variables, one being an AudioSource, and the other being an AudioClip array. I called them recognisable names, and the reason that I did not add a listener like I did for when we were testing the various features that we could make in Unity. This is because the camera will be static, and so the camera won't be moving away from it. I also added a boolean variable that I will use to test whether the music is playing. Although I didn't state private or public, this is technically a private variable, and therefore, will not show in my Unity Inspector menu. This is what I want anyway, since I will only be changing it within code, and do not need to apply any game objects to the variable. Making it public will only mean that it could cause performance issues if this were to be done on a much larger scale. I then began by making a Start() method, which plays whenever you load up the program. What I first want it to do is play the 7th music file that I've put inside the musicSongs array. I want this one specifically, since it's called Minecraft, and I believe it to be a great song for players to open the game to. Using PlayOneShot, it will straight away play a song from the clips provided. I would later find out through longer testing that this means that it would not continue to play another song once it ends.
Next up, I open a new method that I call PlayPause(). This void will be used to either pause the music, or unpause it. It begins very simply by I believe, making the boolean variable the opposite of what it is. I'm not too sure looking back, since this doesn't look like it should work, but it somehow did. I then open an if statement that checks to see if the boolean is true. If it is true, then it pauses the audio source. If it's false, it will unpause the audio source, and allow you to continue listening to music. I applied this method to a button, and it seemed to work well. Finally, I made another void, which I called RandomTrack(). This one is set up so when activated (with a button in my case), the method will stop the audio source, and then play another song using a similar command to the one in the Start void. However, this time I referenced a random song from the array using Random.Range, and then adding a range from the first value in an array (0), to the last one that I have in my musicSongs array. Although it works, I would ideally still like it to not play the same song it currently is playing. However, this is something I may try to adjust with the code later on.
Back inside the actual Unity project, I navigate to the settings page. I applied some more assets, similar to the other pages. Firstly, I made the close button Minecraft themed, and made sure it worked. After, I added a title that has a dirt texture, matching the background of the page, just like the other titles. I then added two buttons which I would apply their designated methods to. I also added a slider which I could use to change the volume of the currently playing music — however, this would take some in depth code to get working properly. Once I was happy with how they looked, I applied the voids to the buttons by dragging my GameManager object onto the button, and selected the void I wanted them to play.
For adding the slider into the script, I had to add quite a few variables and pieces of code. The first new bit of code is actually the pp and ppBack Text variables, which was for the play/pause button. Back inside the PlayPause() method, I changed the text of these variables to either Play Music or Pause Music, depending on if the music will need playing or pausing next. Next, I added a float variable and called it musicAmount. This whole section will later be changed to a very simple piece of code in one line, and not needing the musicAmount variable. However, I will explain my thought process behind this function that I made to convert the current volume of the music to text. I first put string data of the actual volume inside the musicText variable. I then converted that text into the float variable: musicAmount. I did this by using the float.Parse() command, which is similar to the .ToString, but for converting string data into floats. I then took the float variable and multiplied it by 100 since the volume of an audio source is a decimal value between 0 and 1 and I require it to be between 0 and 100. I then needed to somehow make it an integer, probably by rounding. I went on a search, and eventually found this Mathf function. I could use .RoundToInt with this to round it to an integer, which was exactly what I wanted. All that was left to do was convert the float (or now technically integer value) back into a string. I then could change the text of two Text variables to the specific percentage that the volume was at so players could have an accurate slider. I think it is not only a lot better looking, but also links to Minecraft more, since I can make the slider pretty much the same as the one in Minecraft.
After I'd finished configuring the music volume slider, it was time to begin working on the actual point of the game: the clicker. My main idea for the game was going to be that you'd start on dirt, which would give you one score per click. You should then be able to upgrade this block over time to blocks that would give you more score per click. My original code behind this thought wouldn't look horrifically long, however, you can imagine how long it would get if i continued going the same way I was at this point. But for now, let me run through what I was doing.
I started off by returning to the AddScore() method that I was in earlier. As you can see, though, it is no longer just one line of code. I have added a four-part if statement which will check multiple boolean variables to see what block is currently active on the screen. For the first one, I have assigned the dirt image to the bk1 variable. Since it is active, the boolean variable is true, and therefore this if statement is opened. It will then make the variable clickAdd equal to the block1x, which is the integer of which the dirt increases the score by each second. I then edit the score by making it equal to itself and adding the clickAdd variable. Let's say the dirt isn't the active block on screen, therefore, bk1 would be false so it would check the first else if statement. If the second block boolean (bk2) is true, then it will run a very simple few lines of code, but this time adding the block2x integer instead. If none of these booleans are true, then it will print Error in the console.
Next, I added a new void, which I called Upgrade(). This would be used to purchase a different block. This can once again be compressed into a smaller piece of code, but that comes later. The first part I add is an opening if statement to once again check if the boolean variable bk1 is true. If it is, it opens up the statement and begins by checking something else. It checks to make sure that the score is great enough to afford the first upgrade. If it isn't then, it will print Not Enough Credits into the console. However, if the score is equal to or greater than the required price, then it will first set the bk1 variable to false, and the bk2 variable to true. This will ensure that this statement won't open back up again, since the player would have purchased the first block. Then, I take away the cost of the block from the current score. Then, I set the cost variable to the amount I want the next block to cost. The final few lines set the purchase button text to the new cost, so the player knows how much the next upgrade costs, as well as hiding the current block and showing the new one. For example, in the first statement, it would hide the dirt, and reveal a sand block since that is the second block. This will then happen for the next block once you have anough for it, and can continue to happen for many various blocks after.
Next, I wanted to add some text that would appear on the screen briefly to tell you that you don't have enough money to purchase something. I did this by first adding a new method, however, this isn't a regular void like I've been using up to now. Instead, I have made an IEnumerator method which allows me to use yield to wait for a certain amount of time. Inside this method, I first set a new variable that I created as Text and applied the text I wanted for it inside of Unity. Then, on this line of code, I set it to active since usually it would not be active so you couldn't see it. The line after uses the yield command. To make it wait one second, I wrote this, and inside WaitForSeconds, put 1. If I wanted this to wait for a different length of time, I can easily change the value. After it waits for a second, it will then re-hide the text.
Since this method is something that you call to instead of just having it already in code, I had to put StartCoroutine(), and the name of the method inside the parentheses to call to it. I put this inside each of the else statements since then, if the player doesn't have enough money, it will tell you. I thought this was a cool feature since at least then the player won't think the game doesn't work properly if they try to buy something, and it turns out they just don't have enough.
Next up for my clicker game, I wanted to make an auto clicker that you could buy. This would then slowly but surely start giving you money whilst you do nothing. To begin, I created two variables. One was for testing what level of auto clickers you had (the boolean), and the other was for assigning a value to that auto clicker level. For example, if you had one auto clicker, then hasAuto1 would be true, and auto1 is 1, so every second it would generate one amount of score.
Next, I put these variables into the update method and made it give you one a second if you purchased an auto clicker. To do this, I first opened an if statement that checks if the boolean for having the auto clicker is true. If it is, then it will change the value of the score variable by adding to the current amount (+=). It will add the amount of auto1 (which is 1), and because I multiplied it by Time.deltaTime, this means that over the course of a second, it will generate 1. Because of this, it uses decimal values, so I had to change the score variable to a float, otherwise it would give an error. After that, I made it set the score text to whatever the score value is. If the auto clicker boolean is not true, then it will just set the score text to the current score value. I reason I added "0" in the .ToString part, was because this sets the outcome to an integer. Because I don't want the text actually showing decimals, I can just do this. The nice thing with it is that it doesn't round, which is useful since otherwise it would display an incorrect value which could be misleading.
After first making the auto clicker score part, I needed to create the buy function. To do this I first declared a new method which I called AutoClick(). I was then going to just make a button call to this, which would run it. Inside of the void, I first opened an if statement. This checks to see if you don't have the first auto clicker, as well as making sure you have the same or more score than is required to buy it. If both of these demands are met, then it will start by changing the hasAuto1 variable to true. This will avoid this if statement playing again in the future. The line after takes away the cost of this auto clicker from your current score. However, if one or both of the conditions are not met to open the if statement, it will run the IEnumerator method that I made earlier.
As you can see, I then went ahead and added a new screen where you can buy upgrades. I had already done this for the block upgrade, but I forgot to take a screenshot of it, so here's just a sneak peek. As you can sort of see, I used a stone bricks background, not for any specific reason, other than that it looks nice. I did also add a title at the top so it shouldn't confuse any new players. I made sure to make this button play the AutoClick() method, tested it, and it worked!
The next part of my time spent on making my game was me animating pickaxes, which would act as the visual upgrades for the auto clickers. This would be similar to Cookie Clickers pointers, however, these aren't quite as good since they don't add score as soon as they get to a certain point in their animation. I probably could make it by creating a method that adds score which could be called to within the animator. However, I didn't initially think of this, and it would be more difficult later on, so I'm happy with what I'm doing here. As you can see, I will have the pickaxes lined up around the edge of the block, and make a one-second animation of them basically mining the block. This looked cool, and it worked perfectly, except for the fact that the animation would play at a different time to the score going up, depending on when you buy the auto clickers. This is mostly because I had the animations play on awake, so they would all play at the same time. It means that buying the auto clickers will just reveal them at the point of animation that they are in. Although, this is another thing that could probably be fixed by adding a bit of code that just activated the animation whenever you buy them. It didn't really matter in the end, since the score goes up gradually due to the delta time increasing the value of score over the course of a second. Therefore, it isn't really noticeable, and means I would pretty much be doing code for no reason.
A little later, however, I decided to change the auto clickers ever so slightly. Instead of just a pickaxe, I thought I'd make villagers which mine the blocks for me. Although, from the games I researched, I could've used the idea of needing to build a village house or something to keep them in. I decided this was something I could implement at a later date, or just ignore for this game. This works in pretty much the same way as the other version of auto clickers, but instead it changes the pickaxe animation slightly, and obviously includes a villager.
After this, I quickly copied the buying fail method and changed the Text variable to a different one that I added. This time, it would display text which would tell the player that they have bought all the available upgrades. I can then add the code to call to this method whenever the player attempts to buy another upgrade, when there is no more to buy. This is useful since it should give players more reason to understand that they cannot buy more of an upgrade.
And… well… here is the definitely heavily optimised piece of code for checking if the player has a certain auto clicker upgrade. It may look confusing, but it's quite simple. I basically just added a new if statement inside each if statement which is checking if a specific boolean value is true. This will just go through the list of every auto clicker boolean, until it reaches the last one that the player bought. Once it gets a false outcome from an if statement, it will run the else statement which gives a specified amount of money over the course of a second, and sets the score text to the score value after this. This is so heavily unoptimised because if you have every auto clicker purchased, it will go through every if statement that you have every tick that Unity is running at. This is clearly a terrible way of doing it, and I would later go on to optimise it by adding a for loop which shortens the code drastically, and it will also decrease the amount of variables present too.
Oh, and look, another piece of incredibly unoptimised code. This is basically just an extension of the AutoClick() method that I made earlier by just adding else if statements with specific values in which separate it. I did, however, add the new BoughtAll() method, which worked nicely. Now, this is quite simple and is basically just a copy-paste of each statement, similar to the Update() method. Basically, it first checks if you don't have the first auto clicker and if you have enough (1000) to purchase it. This cost increases by a different value each time, and the boolean value changes to the next auto clicker upgrade. Since you can see it goes up to 12, that is how many auto clickers that I have in the game. At the moment, it doesn't make it broken at all, and I think it's a good amount to have in the game. Also, having more means I would have to include a lot more villagers, which is a lot of work and would take a long time to get. So, at least at this point, I don't think there's any point to making any others.
For now, this code works fine, however, I have been told by many people that it is way too long, and I should shorten both these pieces of code, which is probably a good idea, so I'll get onto that.
After my last session went well, but at the same time poorly due to making such large pieces of code, it was time to begin altering it to make it perform better, and make it more readable. To start, I went and changed my variables, since I had so many independent variables that I could've just made into arrays. As you can see, I also ordered everything to be a bit neater. The keen eye may also notice that I added some extra variables to do with commands. I will get to this later on, since I took this screenshot once I finished the commands section, but this is a cool feature that I wanted to add from the start. Explaining this section is relatively simple — I made some arrays that I could just put all the data in from the various variables that I originally had lying around. This not only makes it simpler to look at and store data, but also easier to check for certain things or change data at specific pieces of data within the array. This also is extremely useful for making for loops, since I can use the length of arrays for i, and make i represent certain pieces of data in these arrays. If this doesn't quite make sense right now, I'll move on, and you'll be able to see what I mean in the following pieces of code.
This bulk of text is the entire Update method, compressed from ~100 lines of code, to ~20. Big difference? Absolutely, and I'm sure devices are preferring it a lot more now. I will quickly run through it, however, I do have to admit that I did use AI, ChatGPT specifically, to help me write this. Firstly, while I was optimising the variables, I have a friend that does code in University, and he offered to help me by shortening my behemoth of a piece of code. This wasn't his exact outcome, but I also asked ChatGPT to optimise this code, and it returned something like this, which I eventually went with. Although I have used this tool, I have gone through every line of code to make sure I knew what it was doing. Since we haven't yet learned for loops, I was basically teaching myself, which is why I believe AI is such a useful tool, since if I didn't understand a line of code, I could just ask it to explain it to me. After a while, I understood what was written, so I thought I could probably do something similar, but more independently, another time.
Going into what this piece of code actually does, the first proper line of code creates a new integer variable that we called activeBlockAmount. This is not found within the class, but within a method instead, since I won't need to assign any game objects from Unity to it. Since it is there, it's basically a private variable, which has further performance benefits than having every variable public. This also makes the script within Unity look a lot less messy. Its default state is set to 1, since the lowest the auto clickers are going to be clicking is 1. Also, I should probably explain what this code is now going to do, since the auto clicker upgrades have changed how they give you score. Originally, each level of auto clickers would have a specific value of score that it would generate a second. However, I have now changed this so that each auto clicker will give you the amount of score which a block gives you every time you click it. For example, the sand block gives you 2 score every click. With the improved auto clickers, every second, they will generate 2 score each. Therefore, if you have 3 auto clickers and are somehow still on sand, you will technically get 6 score over the course of a second, or it is the equivalent of you clicking the block at 6 clicks per second yourself. I thought this was such a cool feature, and something that would be drastically better as I add more to the game.
Now continuing with how we have made this, we then open a for loop which foremost creates an integer called i, which we set it to a value of 0. This is because we are going to make it go through an array, changing the value of i to act as the piece of data found at a specific point in that array. We then check to make sure if i is less than the length of the variable blockCheck. If so, it then opens up the for loop, and if it needs to come back to change something later on if it cannot run, it will add one to the i for the next time it loops. Diving inside the for loop, the if statement checks to see what block is currently active by using i as the number for the array. Since i is first 0, it checks if blockCheck[0] is true (the currently active block, which would be dirt in this case). If this is true, it will open the if statement and perform some more code. However, if blockCheck[0] is not true, then it will add one to the i, and try again. This will keep going until the check finally comes back as true, for the full length of blockCheck. We include the length of blockCheck so that if it doesn't find a value, then it can't just go on forever, since it's only for a set amount, and will just come back with an error. The code within the if statement works as follows: it will first set the activeBlockAmount to the blockAmount array with whatever value i is. This means that if sand is active, I will be 1 since the second block is sand and the second value in arrays is 1, since they start from 0, not 1. The activeBlockAmount is the variable that I will later use to set what each auto clicker will give you a second, so it needs to be the same as the current clicks the current block gives. We then added break; at the end, since this means that the for loop will stop and not run again this frame, but it allows the code outside the for loop to run. If I put return, which is quite similar, it would stop the loop, but it would stop the whole method completely, so any extra code outside the loop would also not be able to run.
Once the for loop has got to break;, it then executes a few more lines of code. The first creates a new float variable called totalAutoClickRate. This gets made equal to the activeBlockAmount, and then multiplies that by the autoClickLevel. So, as an example, if the block currently on screen is cobblestone, at this point in time, it gives 10 score a click. If I had 5 auto clickers, then totalAutoClickRate would equal (10 × 5) 50! After that, the score is made equal to the new totalAutoClickRate. The reason this had to become an integer is because it needs to get multiplied by Time.deltaTime, which gradually increases the score by 50 (if we use the same example) over the course of a second. The final two lines of code then changes two lots of text. The Minecoins per second is something new that I added. Firstly, I've now basically made it so the currency in this game is called Minecoins, which I think is perfect for this game since it's the only proper currency that Minecraft has, and it's used in the Bedrock marketplace. This basically displays how many minecoins that you are getting every second, but purely from the auto clickers. I didn't include what you click since this would always be a different value which would not only make it difficult to read, but also difficult to code. Furthermore, Cookie Clicker has their cookies per second counter just like this one, so if it's good enough for them, it's good enough for me. Not only have I now made every text variable it's own array so I don't have two variables for the back and front part, but I also reaslised that I can make one text equal to the other, and then make them both equal to something else. So, therefore, I can change what I would usually do in two lines, instead in one. I made the minecoinsPerSecond text equal to the totalAutoClickRate, and the score text equal to whatever the score value is. And, after a lot of explaining, we have our Update() void.
Although this wasn't that long beforehand, it would've been massive by the time I had added every new block I will later go on to add. So, it was a good thing that I changed this sooner rather than later. For the AddScore() method, I first open another for loop. Now, for this, I used the skills I had learned from the Update() method to recreate this loop myself (although yes, I may have looked back a couple of times). I started by once again making the integer i and setting it to 0. This time I used scoreText as the length that i has to be less than-- oh, never mind. Future Olly here. As you can see, these images are basically the same. However, I forgot to update this image when I realised that I had used Visual Studio's auto code to make this for loop. I did notice in the end, but I needed to use blockCheck instead of scoreText, since scoreText for one wasn't what I needed, and two, only had two pieces of data in. Therefore i would only get to 1, and if it was not true for any of these, it would've logged Error which shouldn't happen, unless there's some logic error in the code (code that works, but doesn't give the desired outcome). This is why you should always check code that gets automatically pasted in for you.-- and I still had the i++ to increase the value of i if it were to not be true on the first loop or few. After that, I once again used blockCheck[i], to check which block is currently active, and once it finds the correct one, it will add the correct amount of score that the block should give you per click. I then instead wrote return, because there is no code that I need to run after, so it closes the method entirely.
Next up is the auto click buying methods. Now, although this still looks long as heck, it has been improved upon, just not as much as I could've. Because I had been coding for so long at this point, I completely forgot to use an array to store the values of the prices for the auto clickers. Instead, my coding friend and I thought that using if statements was the best way to do this, since the cost of the auto clickers didn't go up by the same amount, so we knew that a loop wouldn't work. So instead of just plopping the values into an array, we decided to make this… mess… It also was not easy to code, since we had to use quite a bit of mathematics to make sure the correct values were listed and changed.
To begin, we just needed an if statement to make sure the player didn't have any auto clickers, and had enough money to buy the first one. If this was all true, it would take away the 1000 for the upgrade, set the first auto clicker game object to active so you could see it, increase the auto click level by 1 to say basically that you now have one, and run the void below, which then has a list of more if statements, doing a similar thing, to change the text on the upgrade button, displaying the new cost. Sound like a lot? Yeah, and I bet I could've made it in at least half the amount of lines as this now. Nevertheless, this was something I literally thought of right near the end of the project, and I couldn't be asked to change it since I still had other things I wanted to do. Due to this, this massive block of code still remains in the script, and probably will forever now.
Because of how heavily unoptimised it is, I'm not going to talk through each line, since there isn't much point, considering there's a much simpler way. So, I'll just give you an example of it, if you have 9 out of 12 auto clickers, and you want to buy the tenth. At the start of clicking the upgrade button, it will activate this AutoClickBuy() void. The first thing it will do is check the opening if statement. Instantly, because your autoClickLevel is 8, the first statement fails, however, you do have enough money, since right now, we have 19427 minecoins (current score) which is plenty more than 1000. Nonetheless, our level is not 0, so it moves to the next statement. This one also fails, since the level required to get into this statement needs to be greater than 0 (1+), and less than or equal to 3 (1-3). Even though we would have enough money, it doesn't matter, so we move to the next statement. This one will also turn out false, since our level is still too high, so it moves to the fourth statement. Inside this one, we need to have a level greater than 7, which is so far true, and a level less than or equal to 10. This is also true, so it moves to the next part. Is our score greater than or equal to ((3 × 8 - 9) × 100)? Yes, and it's because the mini equation within the parentheses comes to (24 - 9) --> 15. Multiply that by 1000 and you get 15000. Therefore, this is also true because we have plenty more than 15000 minecoins. Because this all works out great, it opens up the else if statement, and begins by subtracting that same number from our score. Because we had 19427, this would go down to 4427. Next, it will set the auto clicker game object active. Now, you may be confused, and saying, “shouldn't it be pickaxeVillagers[autoClickLevel + 1] since you already have the eighth auto clicker”. Well, you'd be plain wrong, since we have to remember that we are working with arrays, so technically, you have the ninth one - and I'm confused. See how mind-boggling this is? I wrote this and still have a hard time wrapping my head around this. This is why an array for the values would've been so much better, but alas, I'll continue. It will increase the auto click level by 1, and then it calls to the UpdateAutoClickCostText() method, which I made for changing the text on the buy button. This now does similar checks to the buying void, except, it doesn't include the price requirement, and has slightly different margins for the level. Even though our level has been upgraded to level 9, we go into the third statement either way. This very simply changes the cost text to the next cost, using the same equation that I used inside of the other method. And finally, after so long, it finishes. There's no way I should've kept it like this, but at least it got me thinking hard about what to do. And even though it looks incredibly confusing - which it is - at least it works as intended.
Next, it was time to start making the block upgrade void. For this, I would one again use a for loop, however, it would differ a little from the last ones. To begin, I created a new integer array variable that I put some numbers into. This will act as the amount of credits required to buy the next upgrade, and is something I should've done for the auto clicker buying method. I then used blockCheck as the length again, but this time took away one from the length for i. In the opening if statement to check what block is currently active, I used blockCheck again, and this is all to help the game check what block is next in line to get bought. Inside that if statement, there is another one which checks to make sure the player has enough money to buy the next block. Although I probably could've put the if statements together instead of opening two separate ones, this works fine, so I'll keep it like this. If the score is greater than the required cost, then the if statement will first of all set the boolean value for the current block to false, and the one you're buying to true. After that, it will take away the cost from the score, and then set the cost to the new upgrade cost that is listed inside the array above. Now, I could've just used the upgradeCost array to take the money away instead of using another variable, but this works fine. The lines below then change the cost text to the new amount, and also hides the block you had, and shows the new block that you just bought. Finally, I added a return function to end the loop, and avoid any other pieces of code running, which at this point, there isn't any anyway.
After that was complete, I wanted to add a new piece of code — commands. For this to work, I did have to ask ChatGPT, because I had no idea if this was even possible, and therefore had no idea what to even search for. So I thought the best tool to help me out with this would be AI. To begin, I had to make a separate void that I called ChatCheck, which I could apply to a button, which would act as you entering whatever you type. This would then add whatever the user had inputted into the input field, and put it into the string variable: command. The trim() function simply removes any unnecessary spaces that the user inputted, cleaning up the command. I then sent the command into the ParseCommand() void, and it would then use this text in that. I don't think I really needed the separate voids, but because this was something new I was learning, I've just gone along with it.
Inside the new void, for some reason, I trimmed the command again. I don't really know why I did this, but I can probably remove this, and it would still work fine. It then opens an if statement, which checks what the command part begins with. If the first part of the user input is “/give @s minecoin”, then it will split the command into the array commandParts. It then goes on to check that the length of the command has 4 parts to it, and if it does, then it will convert the last piece of data into a float and send that float into the commandAmount variable. Now, if the fourth piece of text isn't a number, then it will fail. However, if it is a number, it goes into the last if statement which checks to see if the number inputted is greater than 100000, or less than -100000. If it is, then it will change the input field text to say that whatever number they put in, is an invalid value. However, if the number is within those boundaries, it will add the amount that the user put to the score value. It will also change the input field to tell the player that they gave themselves whatever amount they put in. Lastly, if any of the other if statements fail, the input field text will just change to “Unknown Command”, which is cool because it doesn't give the player any ideas about what commands could be included. I think this command system is really cool, since I made it work just like how the commands do inside of Minecraft. The fact that you can only add a certain amount before it fails is mostly a feature I added because adding too much causes the auto clickers to start bugging out and not work properly. It is also reminiscent of Minecraft since in most versions, there is a set limit to how much you can enchant a tool to or something.
A little bit later, I also added this small else if statement, which would just detect if the user instead inputted “/help”. If they did, then it would bring up a commands help page by hiding the settings canvas, and then activating the designated canvas. It will also change the input field text, which will stay there until the player comes back and clears it.
My command help page is quite simple, however, I really like how I made it look. It gives just enough information to the player, and looks good at the same time. For the actual commands, I made the text green to highlight them. The information about that command would then sit just below, slanted. The close button on the bottom just closes this page, and reopens the page you last had active, which would be the settings page.
As you can probably tell, I didn't have another great looking background image that I liked, and so this was all I could get. This also heavily limited my title, since there were no obsidian textures that I could use, and therefore I had to settle with this plain, boring gradient title, which I think doesn't match the page at all. Another time, I would at least make the colours darker to blend in more, or just make a different background for which I could make a better looking title for. This is one of the few pages I don't think looks great, but it does its job, and hopefully won't be super common to see anyway. Of course at the moment I only have these two commands. If I was to add more, this would probably have to relate to different content that I add in the future, or maybe I add some commands to change the block that you are currently on or something. This could basically give you a way to use blocks and stuff that you already bought, which could be very useful for testing.
Three stages of upgrading my PlayPause() method went well… To start, all we did was change the text array variables to change each other on one line. I then realised that this stopped the play/pause method working completely, which was strange. I would later realise that I changed the way that the music played, and so when the music would stop playing, the musicPlaying boolean would be true for a split second, making a random track play instead of pausing. I would eventually realise this, and instead put the changing musicPlaying variable inside the if statements, which seemed to work. I thought I'd give ChatGPT one last try to see if I could get it any better, and they just put the boolean outside the if statements, but at the end, so they would run, and then it would change the variable after, depending on whether the music was actually playing. As you can see, it ensures the boolean is linked up properly to the actual state that the music is in to avoid anything going wrong. Although at this point, I could do without the boolean variable, it will become apparent in a bit how important it is.
A few things in this stage were useful to help me improve my productivity, or just overall happiness, you could say. For starters, I got the music to play a random track once it ends, since before, it would just stop. This was as simple as making an if statement, checking to see if the music is no longer playing, as well as making sure the boolean variable is true, so that it isn't playing because it has been paused. This is linked to the issue I had with the play/pause, since it would just play a random song if the boolean was changed too soon.
Also, as you can see, I got the music text line of code down to only one line, which is crazy cool to see compared to my original 5 lines. I made this small if statement which would set the percentage instead to OFF, if the volume got to 0. This is great since it's what happens inside of Minecraft's settings, and I also think it looks better than just 0, since technically it is off.
Next up, I found this extremely useful line of code for disabling the canvas debug menu, which would occasionally pop up when I would be testing the game. I don't know why this happens and what it's useful for, but this line of code disables it. Furthermore, I found out how to play a specific song from the music clips on startup, so Minecraft will begin playing every time you start the game. I think this is something that just had to be included, since at least then you hear the start of this song every time, and this is quite a good one as a starting song, in my opinion.
Next up, I found a really easy way to apply the same settings to multiple images that you bring into your Unity project. Since I had brought over 30 new block images, I didn't want to change the settings for each one individually. Instead, I went and found that there is a way to create presets that you can apply to multiple things that you select. This is done by first clicking on an image that has the settings applied and ready to go. You then click the middle button with sliders, which can be found on the screen just inside the Inspector menu. This menu then pops up, and I clicked Create New, and named it TextureImporter. I could then select every new image, go here, and click on the new preset I made, and boom, they are all ready to use. This is something that is quite simple once you know it, but it will also be such a great time saver for the future.
So, I now have a few more blocks to buy in the game. This whole process took ages since I not only had to apply each and every texture to certain images, but also because I had to order them in a specific way that you would most probably find them throughout a regular Minecraft play through. This also clearly meant I had to alter the code for buying blocks slightly. This was a process that took ages, and didn't work properly at first due to me adding an extra value inside the array as a way to check once the final purchase had been made.
Now, I've attached both pieces of code so you can see the difference, but the right side image is the final result which works perfectly without needing an extra value.
Here is a link to a video of me playing the game up to this point in the creation of the game.
Here is a small change that I made to the variable lists. Inside of Unity, I added these headers by adding in a simple line of code. This just breaks up the sections I have, and makes everything a bit clearer, and keeps my variables a bit more organised. Furthermore, I learnt a new way to move lines of code. If I hold alt and use the arrow keys, I can move one, or multiple lines of code around, which is really useful if I have something put in the wrong place and it needs moving.
I also found out that there is a different void called Awake(). This works very similarly to Start() in Unity, however, it actually plays even before Start(). At the moment I don't have a use for it and I'm unsure as to when it would actually be required, but it's good to know that it is a thing I can use.
I have now also removed the button hiding the main screen whenever clicking to go to the upgrades or settings screen. This means that it will no longer freeze the drop-down sign mid-animation, since the canvas is never not set to active, meaning that it will continue to play, and finish the animation, even if you are on a different screen.
Well, after a crazy amount of work, you have finally got to the evaluation. I really hope you read every word since I spent so long writing this, and that's time I'm never going to get back.
For starters, I think this project went well because, I actually got a game that you can pretty much complete. Of course, there isn't a lot of gameplay to be had at this stage. However, if you play it without using the cheating commands, then I would've thought that this would give you quite a while of content to, enjoy? Now, although I'm really happy with how this came out, I'm going to be very critical, as if the game has actually been released. For starters, I think the game has a great start screen. It is resembling Minecraft well with the moving background, has an awesome title, and the Play button, with an info box at the bottom of the screen telling you what to do if you aren't smart enough to know. Once you click Play, the game brings you to the main screen, where you can begin clicking the dirt block and gaining Minecoins at an incredible 1 per click. Once you have enough to start upgrading, you can click the netherite upgrade template to navigate to the upgrades' menu, which I thought was a perfect image for that button. By the time you're there, you can try purchasing some stuff, but will get obviously rejected if you don't have sufficient funds. This is due to the clear, red text that pops up on the screen, telling you that you don't have enough. I still think this is a great feature which uses a unique method that I wouldn't have otherwise knew existed. Furthermore, once you do have enough, you will soon realise that there are lots and lots of blocks that you can buy, which keeps the game going for a while. I also thought that making the blocks progressive like how you would find them during a play through was neat. And having the end ones either as quite rare, or just a bit more special than others, was a nice touch in my opinion. Then there's the auto clickers. I thought the little animation for them is quite cool, and the way they work was, at least I thought, a genius idea of mine. Then there's the settings menu. I thought the play/pause button having the changing text was quite a cool feature, and the random music worked decently well. The fact I got some good, working background music was a win in my books, and making the volume slider was the cherry on the cake. Not only did mine look cool, but people starting asking for the code for this (yes, I'm taking full credit for anyone else's volume sliders that include a number percentage for the amount). Later on, I also went on to shorten the code to one fine line, and improve upon it even more, by making it more like Minecraft, having it display OFF, when it got to 0. Talking of code, even though I had ChatGPT and a friend help me do it, I did shorten (most of) the code in the scripts to a much nicer looking and optimised versions. I think this shows how keen I am to code, since I had to teach myself quite a bit. Lastly, I think the command functions are an awesome way for testing the game. Either using them as developer tools, or something cool that players can experiment with. Furthermore, I thought it was great how similar to Minecraft's commands that I made them, and originally thought it was something that could never be done, but ending up proving myself wrong.
Now, onto what I thought could've been better within this project. For starters, I think it's obvious that there could've been so much more gameplay within it, and I had so much room for improvement in areas that I left the game quite bare. For example, I only got round to adding two upgrades. Even though they work well, I could've added more. Furthermore, I wanted to add something like a rebirth that you have in Roblox games. Instead, I would call it enchant multiplier, or something, and it would increase all earned money by a certain amount. You had to first buy everything, reach a certain amount of money and then reset everything, but have a multiplier increase. This could then be increased further, and wouldn't hold people back from playing the game, since they could just continue playing to see who could get the highest amount of multipliers, never having to stop due to “finishing the game”. Now, obviously, it wouldn't be that simple, since I may have to disable cheat codes, but it is still something cool to think about. Another thing that was playing on my mine was getting achievements in the game. Not only could these just be a symbol of the great player that you are, but they could also give you rewards that encourage players to continue playing. Lastly, I think having more to the game than just clicking a block and having auto clickers was a missed opportunity. I had ideas for making a similar game to Clash of Clans within the game, where you could build a village, and have to withstand waves of mob attacks. I had ideas that you could go exploring, loot structures, kill mobs, and yet, I couldn't implement any of that. Now, I know I didn't have a lot of time, come the end, and I spent a week or two just learning what I could add to make a clicker game. But still, if I had put even more time into this, I could've added so much more, and yet, it just looks like any basic clicker game with a Minecraft retexture (see what I did there?). I think in some regard, I'm being a bit hard on myself, but this is also a great time to reflect. I now know what to improve upon when it comes to my upcoming projects for college, as well as later in life for work. Knowing what I know now, I can probably make the same game in around half the time, and possibly even better. Two things that I certainly should've added, at least more of in one case, is sound and particle affects. Although the game keeps you immersed quite well already, the lack of sound effects when clicking buttons and travelling between pages is lacking massively. Furthermore, the lack of particle effects not only is a disappointment due to the fact I spend a lot of time at the start of this project learning about them, but also the fact that Minecraft has so many particles that I could've used, and yet I didn't use any.
At times, I have thought about publishing this game. If I were to publish it onto some website that you could play it on, download it from, possibly even the Google Play Store, I would have to make some drastic changes. For starters, the game cannot use Minecraft's textures. Although there is that MineClicker game that I did research on, it makes a lot more sense to design every texture myself, so it cannot be seen as direct copyright, and just me reusing the whole Minecraft, blocky game idea. The only problem with that is that it would take a lot longer to make every detail than to just download it off of a website, and thank Minecraft for making getting their assets so easy. But that's why making a game that doesn't require a lot of effort is a good starting point, since I now won't have to spend as long on the designing phase which includes where I put graphics and the code I use, since I already have a baseplate for all of that. Furthermore, before publishing, I would have to make sure there is more gameplay to actually be had. Since although I could provide a lot of updates, people would quite commonly say that they'd prefer waiting a while longer for a game that is mostly finished first, than a game with very little gameplay. Updates coming out daily, slowly increasing what is available, leads to players getting bored fast, which is not what you want when releasing a new game. You want to continue growing after a week, and not fall into a pit of darkness, never to be seen again.
To conclude my conclusion, I would say that the main thing I would add if I were to do something like this again would be to especially add the rebirth/multiplier enchant. This is due to the fact that it provides more content once the players think their time is over, and it gives you more opportunities to add content. You could make some new mini-game only accessible once you rebirth 5 times or something. Obviously, you therefore don't want the gameplay to be completely dead before that stage, since players will get bored and not want to progress to that stage. However, having something else that feels like a reward after playing for a while is certainly something that needs adding, as well as achievements.
I think that this project was made for us to start getting a better idea for what we want to do when we finish this section, first year, or whatever. Whether that is you wanting to be a generalist, a coder, an artist for the game's graphics, or something else. Because this project had us working alone, managing each stepping stone to creating a game, it splits the class apart and has helped us know what section we enjoy the most. I also think this has helped us understand our strengths and weaknesses, which links to what we want to be. This all becomes very important as we progress into large, group projects, since the whole class needs to be put into teams with different people doing what they do best.
Overall, though, I think this project went quite well for me. I got a somewhat completed game, discovered a lot of new code that I can implement into other games in the future, and found out that I primarily like code. Also, I quite like animation, which is something that I might try to do more of, but with 3D models in the future.