A lot of the most successful Android apps on the Google Play Store are games. Getting started with Android game development and building your first game can be daunting as there are many game engines to choose from such as Unity, libGDX, Unreal Engine and Corona SDK among others that require you to use different programming languages.
I have put together this tutorial on how to make a simple two dimensional game for Android using the popular game engine Unity. The game we will make in this tutorial will be GemBester which is a stripped down clone of the match 3 casual game Bejewelled by PopCap Games. In addition to the gameplay the game will contain 2D graphics, sound effects and a scoring system.
Read on and we will cover some of the benefits of using the Unity game engine for Android game development before we start building our first game for Android using Unity.
What are the Benefits of Using Unity for Android Game Development?
As mentioned in the introduction we will be using the Unity game engine in this tutorial for building a simple 2D game for Android.
The Unity game engine is feature rich easy to use game engine that will improve your productivity on building your game.
The Unity game engine has mutli-platform support, this allows you to create your game once and deploy it across many different platforms. Some of the platforms supported by Unity includes:
- Desktop platforms such as Windows, Mac and Linux
- Mobile platforms such as Android and iOS
- Console platforms such as PS4, Xbox One and Nintendo Switch
Unity offers a generous free tier for using the game engine even for commercial purposes which reduces the upfront costs for development. Providing you make less than $100,000 in revenue or funding from the use of the Unity game engine you will qualify to use the free to use Unity personal license.
If you create a well received game and your revenue grows the pricing for the Plus and Pro licenses at $40 per month and $150 per month respectively are quite reasonable for the value you get.
Unity also has an Asset Store where you can purchase assets for use in your game such as 2D graphics, 3D graphics, audio files and much more to help you save on development costs.
Another strength of Unity is such as popular game engine there are many free resources such as tutorials and YouTube videos available online to help you were you may get stuck using it.
How to Install Unity
In this section of the post I will take you through how to install the Unity game engine to allow you to start making games for Android.
We will be using the Unity Personal license for an Individual which is free to use providing you make less than $100,000 in revenue or funding from game development.
First we will navigate to the Unity Store and select the “Get started” button under the Unity Personal license for an Individual.
Next in the “First-time users” section select the “Start here” button.
Review the terms presented then select “Agree and download” button.
This will start the download of the UnityHubSetup application.
Once the download is complete, run the UnityHubSetup Application. Install the latest version of Unity using UnityHub by selecting the “Install” button.
Next we will create a Unity ID, then we will sign in to your Unity ID in UnityHub while the latest version of Unity is being installed. After you have signed in select continue and wait for Unity to finish installing.
Once Unity has finished installing select the “Launch Unity” button.
This will load the Unity editor with a sample project. For now we will close the Unity editor and in the next section of this tutorial we will create our first project in Unity.
Creating your First Unity Project
In this section we will be creating our first unity project for our 2D puzzle game “GemBuster”.
To create a unity project, open the Unity Hub application. Navigate the Projects section and select “NEW”.
Select the 2D Template, enter the Project Name as “Gem Buster” and select the “Create” button.
This will create and load the Gem Bester Unity project in the Unity Editor.
Configuring Unity Project to Build for Android
Next we will set up our Unity environment to allow us to build Android apps.
Open up Unity Hub then navigate into the “Installs” section.
Select the 3 veritical dots, and select “Add Modules”
Check the “Android Build Support” module and check the “Android SDK & NDK Tools” module and the “OpenJDK module” and select the “Next” button and follow the prompts to install the modules.
Once the download is completed, open your Unity project in the Unity Editor and open the build settings by selecting “File” then “Build Settings”.
Select the “Android” platform then select “Switch Platform”.
Select a connected device from the Run Device drop down list and select “Build And Run”.
Enter a name for the APK and select Save
This will run the Unity project on your Android device as per the photo below.
Creating GemBuster (A Bejeweled Clone)
What We Will Create
GemBuster is a simple clone of the casual match 3 game Bejeweled created by PopCap Games which is also responsible for creating other popular casual games such as the Plants vs. Zombies Series and Peggle.
The GemBuster game will feature an 8 by 8 grid of gems that will start in a random order. The player will be able to select a gem and move it to an adjacent tile in the grid to switch positions with the gems. If gems of the same are positioned in the grid 3 times or greater, the gems will be removed from the grid, the player will score points and the existing gems will fall into the empty spaces spawning more gems into the grid to fill all empty spaces.
<GemBuster Screenshot>
We will utilize game assets from the popular free to use Kenney.nl game asset packs. The sprites for the gems will be sourced from the Kenney.nl puzzle asset pack. The sound effects for the gems falling with be sourced from the Kenney.nl impact sounds asset pack. <Assets for the UI>.
The game will be built using Unity targeting release for Android.
Step 1: Importing Game Assets into the Unity Project
First we will need to download the following free to use asset packs from Kenney.nl.
- Puzzle pack – https://kenney.nl/assets/puzzle-pack
- Impact sounds pack – https://kenney.nl/assets/impact-sounds
- Interface sounds pack – https://kenney.nl/assets/interface-sounds
Next we will open our GemBuster project in Unity and add some directories into the Assets folder.
We will create the following directories:
- Sprites
- Sounds
- Scripts
- Scenes
- Prefabs
Importing Sprites
The “Sprites” directory will contain all of the images we want to use in our game. Unzip the Kenney.nl Puzzle Pack archive and copy the following images we will use for the 6 different colored gems into the “Sprites” folder in Unity.
Importing Sounds
Have a look through the impact and interface sound packs mentioned above and offered for free by Kenney.nl. We will need three sounds to add to our GemBuster game later in this tutorial.
Find a sound you like for each of the actions below and copy them into the Sounds folder inside the Assets directory.
- Selecting a Gem
- Swapping a Gem
- Clearing Gems
I chose the following audio clips from the Kenney.ml impact and interface sounds pack for GemBuster.
Saving the Game Scene
Make sure to save the Scene in Unity and give it the name “GameScene”. Place the GameScene file in the Scenes folder in the Assets directory.
Step 2: Creating a Grid and Displaying the Gems on Screen
In this section of the tutorial for the GemBuster game for Android we will implement a 8×8 Grid of Gems of different colours to be shown on the screen in a randomized order.
Creating the Prefab for the Gem
In this section of the tutorial we will introduce the Unity concepts of GameObjects and Prefabs.
In Unity a GameObject is an object that is placed inside a Unity Scene that always has a position and rotation. Components can be added to GameObjects such as a Box Collider, Light, SpriteRenderer or a Script to change it’s appearance or functionality.
In Unity a Prefab is a template of a GameObject which enable you to save the configuration details of a GameObject in an Asset that you can reuse throughout the Unity Scene.
We will need to create Prefab of one of the gem sprites that we will use in our Script for generating a grid of gems. Before we create the Prefab of the gem we will need to create and configure it as a GameObject first then convert the GameObject into the Prefab saving all of it’s configuration details.
To create the GameObject of a gem that we will then turn into a Prefab navigate into the Sprites folder inside the Assets folder, select the Sprite of the grey gem and drag and drop it into the Unity Scene Editor. Locate and on the GameObject you have just created for the grey gem in the Unity Scene Hierarchy. Next will will configure the GameObject of the grey gem and set the scale of the X and Y to 1.25 on the Transform vector to increase the size.
Now we are ready to create the Prefab of the grey gem, navigate to the Prefab directory in the Unity Assets folder then drag and drop the GameObject of the grey gem from the Unity Scene Hierarchy into the Prefabs folder. This will create the Prefab and now you can delete the GameObject of the grey gem.
Creating the GridManager Script
Next we will create our first Unity script that will be used for creating an 8 by 8 Grid of Gems.
In Unity a Script is code you write in the C# programming language to control the behaviour of GameObjects in your game. Scripts are written using a code editor and consist of classes and methods. Scripts can be added to GameObjects to be displayed in your Scene in Unity.
I recommend you bookmark the following resources below that contain documentation to help you to write C# scripts in Unity.
To create the Script, navigate into the Scripts folder inside the Assets folder. Left click on the Assets folder, select “Create” then “C# Script”. Give the Script the name “GridManager” and select enter key.
Now that the Script has been created, open it up in a code editor and copy and paste the following C# code into the GridManager.cs Script.
As mentioned above Unity Scripts are written in the C# (pronounced C Sharp) programming language. If you have experience with Java, you may notice there are some similarities in syntax.
In Unity, public variables in Scripts can be configured against the GameObject in the Unity Inspector. In the GridManager script we have a mix of the following public and private variables.
- An instance of GridManager, that is a static variable that has public visibility
- Two integer variables with public visibility, representing the number of rows and columns in the grid
- A private multi dimensional array of GameObjects representing the Gems shown in the Grid, with the column and row of the Gem in the Grid as indices to the array
- A public variable for the list of Sprites to be populated with a Sprite for each color of the Gem
- A public variable for the GameObject of a Gem Prefab that we will use for creating each of the Gems in the Grid
Also in the Unity Script for the GridManager we have three methods. A Start() method, an Update() method and the GenerateGrid(float, float) method. Our class for the GridManager Script extends the MonoBehaviour class.
The Start() method is called in a Unity Script that extends the MonoBehaviour class when the game is run. In our Start() method we first set the GridManager instance variable using the GetComponent method.
After that the Gem Prefab is used to obtain the width and height of each Gem to be shown in the Grid by getting the SpriteRenderer from the Gem Prefab and accessing the bounds.size variable on the SpriteRenderer. Finally in the Start() method we set up the 8 x 8 Grid by calling the GenerateGrid(float, float) method passing the Gem width and height as parameters.
The Update() method is called in a Unity Script that extends the MonoBehaviour class at the frequency of once per frame. For our GridManager Script we have left the Update() method empty.
The GenerateGrid(float, float) method is used to create the 8 x 8 Grid of Gems. First in the GenerateGrid method we initialize the multi dimensional array of Gems using the number of columns and rows that are to be provided to the Script in the Unity Inspector.
Next we start two for loops to create a Gem GameObject at each row and column in the Grid.
The Gem GameObject is created using the Instantiate(…) method with the Gem Prefab as the GameObject to be replicated, at a calculated position using a 3D Vector with the rotation matching the rotation of the Prefab of the Gem.
The position of each Gem is calculated using the coordinates of the Grid (using the transform.position 3D Vector) and adding the Gem width or Gem height multiplied by the index of the column or row.
Once a Gem is created using the Instantiate(…) method, it gets assigned to the applicable column and row in the multi dimensional array. Then a parent child relationship is created between the Grid and the Gem using transform.parent variable on the Gem.
The Sprite to be used for the Gem (which is different for each Gem color) is set using the SpriteRenderer on the Gem by assigning the sprite variable on the SpriteRenderer of the Gem to a random Sprite in the List of Sprites containing each Gem color.
Creating and Configuring the Grid GameObject
Now that we have a Script for the GridManager the next step will be to add a Grid to be shown in the Unity Scene.
To do this we will first open the GameScene in Unity from the Scenes folder in the Assets directory. Next we will add an empty GameObject to the GameScene by clicking the right mouse button in the Unity Scene Hierarchy and selecting “Create Empty”. Rename the GameObject you have just created to “Grid”.
Next we will add the GridManager script to the Grid GameObject in the Unity Inspector by selecting the Grid GameObject, then selecting the “Add Component” button, selecting the “Script” option then selecting the “GridManager” Script.
Now that the GridManager Script has been added to the Grid GameObject next we will populate the public variables from GridManager Script in the Unity inspector.
Because we want an 8 by 8 grid enter 8 in the Rows and Columns fields on the Grid Manager Script. Under the Gem Sprites public variable for the Size variable enter 6 as we have 6 different color Gems, this will create Elements 0 – 5 in under the Gem Sprites variable.
Next navigate into the Sprites folder in the Assets directory and locate the 6 different Gem Sprites, drag and drop each Gem Sprite into one of the Element slots.
Finally navigate into the Prefabs folder in the Assets directory and locate the Gem Prefab you created earlier. Drag and drop this Gem Prefab into the Gem variable in the Grid Manager Script in the Unity Inspector.
Now if you select the Play button in the Unity Editor you should see the 8 by 8 grid of Gems in a random order shown on screen. You may need to reposition the Grid GameObject if the Gems are spilling over the bounds of the screen so that all of the Gems are shown correctly on screen.
You may notice that we do have some Gems in the Grid that are shown as 3 or more in a row either vertically or horizontally this is something we will address in later stages of the tutorial.
Step 3: Adding Touch Controls to Swap Gems
In the third step of the tutorial for creating the GemBuster game we will create a Script for the Gem and implement basic touch controls to select, unselect and swap gems.
Creating the Gem Script
Create a new C# Script in Unity by navigating the Scripts folder inside the Asset directory, right click the mouse button, select “Create” and click on “C# Script”. Rename is to “Gem” and open the script in the code editor.
Copy and paste the following C# code into the Gem.cs Script.
All of the variables in the Gem Script are private. The following variables are defined in the Gem Script.
- A variable for the color to be applied to the SpriteRenderer on the Gem when it is selected
- A variable for the color to be applied to the SpriteRenderer on the Gem when it is not selected
- A boolean variable which is set to true if the Gem is selected, otherwise it is set to false
- A Gem variable which references the previously Gem selected which is used for swapping the previous Gem with the currently selected Gem
- A SpriteRenderer variable which is used for applying a color against the Gem Sprite if it is selected or unselected as well as changing the Gem Sprite if two Gems are swapped
The following methods are defined in the Gem Script.
- Start()
- Select()
- Unselect()
- OnMouseDown()
- IsSelectedGemAdjacent()
- SwapGem()
The Start() method is used to initialize the Gem. It retrieves the SpriteRenderer and defaults the Gem to unselected.
The Select() method is used to handle the selection of a Gem in the 8 x 8 Grid. The Unselect() method will unselect the currently selected Gem.
The IsSelectedGemAdjacent() method calculates the adjacent Gems by sending a raycast in the up, down, left and right directions of the selected Gem and adding the GameObjects that produced a collision into a List. This List is then checked if it contains the previously selected Gem. If this is the case, the selected Gem is adjacent to the previous Gem and the method will return true otherwise it will return false.
The SwapGem() method is used to adjacent swap gems that have been selected one after the other. This is achieved by swapping the Sprite of the Gems with the help of a temporary value for the Sprite.
The OnMouseDown() method is used for handling touch events on the Gem. It determines whether the Gem needs to be Selected, Unselected or Swapped with an adjacent Gem using a series of conditional statements.
Updating the Gem Prefab
Now we will to make two changes to the Gem Prefab we created earlier in this tutorial. We will need to open the Gem Prefab in the Unity Inspector for editting, to do this, locate the Gem Prefab inside the Prefabs folder in the Assets directory and double click on it.
First we will need to assign the Gem Script we have just created to the Gem Prefab. To do this, select the “Add Component” button, select “Scripts” then click on the “Gem” Script.
Next we will need to add a Box Collider 2D component to the Gem Prefab. This is required so that when we tap on a Gem to select or swap it, the taps will only be registered if there is a collider present on the GameObject. To add the Box Collider 2D to the Gem Prefab, select the “Add Component” button, select “Physics 2D” then click on “Box Collider 2D”.
Once you have made these changes to the Gem Prefab, the Unity Inspector should show the Gem Script and the Box Collider 2D components added to the Gem Prefab as per the screenshot below.
Save the changes to the Gem Prefab then proceed to the next section of the tutorial.
Configuring Physics 2D Unity Project Settings
For the last part of the step to ensure the raycasting will work correctly when detecting adjacent gems we will need to disable the “Queries Start In Colliders” flag in the Unity Physics 2D Project Settings.
To access the Unity Project Settings, select the “Edit” menu and select the “Project Settings…” menu item.
Select the “Physics 2D” option in the left side bar and uncheck the “Queries Start In Colliders” flag.
Now if you run your the GemBuster game you should be able to swap adjacent Gems in the 8 x 8 Grid as per the screen capture below.
Step 4: Implementing Matching, Clearing and Falling Gems
In the forth step of this tutorial we will be finalizing the game logic that is required to be built for the GemBuster game.
First we will modifying the GridManager Script to update the Grid creation method to prevent matches of 3 or more Gems found in the initial Grid generated.
After that we will create some methods to detect matches of 3 or more Gems in the Grid using ray casting against the two Gems that have swapped positions. Once matches are detected we will create some methods to clear those Gems from the Grid.
Finally in forth step of the tutorial we will implement game logic to drop gems that sit above cleared gems and spawn new games where required to fill the 8 x 8 Grid of gems.
Modifying the Grid Creation Script to Prevent Matches in the Initial Grid
We will start this section by opening up the GridManager.cs Script in a code editor and we will make some changes to GenerateGrid(float, float) method along with adding a new method RandomSpriteExcluding(List<Sprite>).
In the GenerateGrid(float, float) method we change how we assign a new Sprite to a Gem in the Grid. Instead of selecting any Gem Sprite at random we will create a List of Sprites to choose for the Gem and we will first exclude the Sprite of the Gem to the left of the new Gem, if it exists. And we also exclude the Sprite of the Gem underneath the new Gem, if it exists. Then from this List of possible Sprites we select a random Sprite ensuring we don’t end up with a match of 3 or more in the initial Grid.
See the code excerpt showing the changes in the GridManager.cs script below.
If you implement the changes above in the GridManager script, when you run the GemBuster game, you will see that the 8 x 8 Grid will start with no matches of 3 or more in a row as per the screenshot below.
Detecting and Clearing Matches of 3 or More Gems in the Grid
In this section of the tutorial we will alter the existing Gem.cs Script to introduce some new methods to detect and clear matches of 3 or more gems in a grid.
See the code excerpt showing the changes for implementing the match finding and clearing game logic in the Gem.cs script below.
Three new methods have been created in this code excerpt.
- FindHorizontalMatches()
- FindVeriticalMatches()
- ClearMatches()
The FindHorizontalMatches() method returns a List of GameObjects which are Gems that match the same color of the swapped Gem in the left and right direction. Ray casting is used in the Vector2.left and Vector2.right direction of the swapped gem to check if the adjacent gem matches the swapped gem’s color.
If there is a match the gem is added to the List and the ray casting is performed again on the adjacent gem until either the adjacent gem’s color doesn’t match or the left or right side of the grid is hit and there are no more gems to compare.
The FindVeriticalMatches() method also returns a List of GameObjects, it uses the same logic defined in the FindHorizontalMatches() method but instead of going in the Vector2.left and Vector2.right direction when comparing the color of adjacent gems to the swapped gem it moves in the Vector2.up and Vector2.down direction.
The FindVeriticalMatches() method will check that the swapped gem matches in the adjacent gem’s color in the up and down direction until the color’s no longer match or the top or the bottom of the grid is reached and there are no more gems to compare.
The ClearMatches() method is responsible for calling the FindHorizontalMatches() and FindVerticalMatches() methods after gems are swapped in the grid. If there are at least two gems in the List of horizontal matches or the List of vertical matches these gems will be cleared from the screen by using the SpriteRenderer on the Gem and setting the Sprite to null. At least two gems are required instead of three because the swapped gem is not included in the count of matches.
The ClearMatches() method also calls the DropGems() method on the GridManager instance if there are at least two vertical or horizontal matches. This method will be covered in the next section of this tutorial.
In additional to the three new methods, the OnMouseDown() method has also been altered slightly. After the user has swapped two adjacent gems the ClearMatches() method will be called twice against gem that was swapped.
If you implement these changes and run the GemBuster game, you will see that when you swap two adjacent gems and a match of 3 or more gems is detected, they will be cleared from the grid as per the screen capture below.
Implementing Falling and Spawning Gems
In this section of the tutorial we will update the GridManager.cs Script to make gems falls if there are cleared spots underneath. In addition to this we will implement spawning of new gems after gems are cleared so that they can be replenished in the 8×8 grid.
See the code sample of the GridManager.cs Script containing the functionality for implementing falling and spawning Gems.
Three new methods have been added in this GridManager Script.
- GetDroppableGems()
- GetSpawnableGems()
- DropGems()
The GetDroppableGems() method returns a list of x and y indices of the multi dimensional array of Gems that are sitting above a blank spot in the Grid.
The GetSpawnableGems() method returns a list of x and y indices of the multi dimensional array of Gems that can have a Gem spawned in that location from the top of the grid.
The DropGems() method uses both the GetDroppableGems() method and the GetSpawnableGems() method to make sure that any droppable gems fall to the correct location in the Grid and new gems are spawned correctly.
The DropGems() method will first use the GetDroppableGems() method and get a list of x and y indices that contain gems that can drop. Then it uses a while loop to lower the position of each droppable a gem one space at a time until no more droppable gems are left.
After that the DropGems() method will call the GetSpawnableGems() method to retrieve the list of x and y indices that can have a gem spawned into them. For each of these x and y indices a random Sprite that will not cause a match to be created is spawned and placed at the x and y coordinates in the Grid.
Finally each Gem in the Grid is retrieved and the GetMatches() method is called on the Gem to check if there are any new matches requiring the process around matching, clear, dropping and spawning of gems to be repeated.
If you implement these changes to the GridManager.cs Script and run the GemBuster game, you will see Gems will drop if there is an empty space underneath and new gems will spawn from the top as required as seen in the screen capture below.
Step 5: Adding Sound
Back in Step 1 you would have downloaded some sound packs from Kenney.nl and added three sounds into the Sounds folder in the Assets directory.
In this step of the tutorial we will be updating our Gem Prefab and Gem.cs Script to play the following three sounds during game play in the GemBuster game.
- Selecting a Gem Sound
- Swapping a Gem Sound
- Clearing Gems Sound
We will start by making the following changes to the Gem.cs Script.
- Add three public AudioClip variables
- Adding code to the Select() method, the Swap() method and the ClearMatches() method to play each of the Audio Clips
See the code excerpt from the Gem.cs Script below.
Next we will need to make some changes to the Gem Prefab to set the Audio Clips to the variables on the Script and then add an Audio Source component.
Open the Gem Prefab, then open the Sounds folder in the Assets directory and drag and drop the sound files into the relevant Audio Clip variable.
Then to add the Audio Source component to the Gem Prefab, select the “Add Component” button, select “Audio” then select “Audio Source”.
Once you make these changes and run the GemBuster game, you should hear different sounds playing when you select a gem, swap a gem or clear gems from the grid.
Step 6: Adding Scoring and a Count Down Timer
In the sixth step of this tutorial we will be adding a scoring system to the game as well as a count down timer that we will be displaying in the game user interface.
Adding a Canvas with Text Fields
We will start this step of the tutorial by adding some text fields to the screen for showing the current score, high score and a count down timer.
The Canvas can be added to the screen by right clicking the mouse in the Unity Scene Hierarchy, selecting “UI” then selecting “Canvas”.
Next we will add a Panel to the Canvas by right mouse clicking on the Canvas and selecting “UI”, then “Panel”.
Give the Panel the name of “GameUIPanel” and make sure the Panel is fully transparent by unchecking the Image checkbox.
Next we will add three text fields to the panel by clicking the right mouse button on the panel in the Unity Hierarchy, selecting “UI” and clicking on “Text”.
Configure each of the three Text fields in the Unity inspector by giving them a recognisable name, setting the text to be shown, setting the font size and configuring the horizontal and vertical text alignment as per the screenshot below.
After configuring the panel for the game user interface, repeat the relevant parts of the process above to create a second panel underneath the Canvas to be shown when the game ends.
Add three Text fields to this panel, one for displaying “Game Over” text and two others for showing the final score and the high score.
Add a Button to the panel to restart the game from the Game Over screen by clicking the right mouse button on the panel in the Unity Hierarchy, selecting “UI” then clicking on “Button”.
Expand the Button in the Unity Hierarchy and select the Text element underneath the Button and update the Text to “PLAY AGAIN” in the Unity Inspector as per the screenshot below.
Make one additional change the GameOverPanel to load as inactive (hiding it from the user) by unchecking the checkbox next to the name of the panel in the Unity inspector as per the screenshot below.
Setting up the GameManager
Next we will set up the GameManager which will be responsible for keeping track of the game score, the game count down timer, showing the game over screen and restarting the game.
Create a new Script called “GameManager” and copy and paste the following code inside.
Next create an empty GameObject in the Unity Hierarchy and give it the name “GameManager”. Then add the GameManager Script to the GameManager GameObject.
Next drag and drop the relevant Text fields, Panels and Buttons from the Unity Hierarchy into the public variables in the Unity Inspector for the GameManager GameObject.
Finally, we will make two minor changes to the Gem Script.
The first change is in the OnMouseDown() method where we will add a condition to the if statement to return null at the start of the OnMouseDown() method to check if the game is over using the boolean variable from the GameManager. This will allow us to prevent the user from interacting with the game play if the game is over until the game is restarted.
The second change is in the ClearMatches() method where the IncreaseScore() method on the GameManager is invoked to add points to the score after calling the DropGems() method on the GridManager.
See the code excerpt below containing the changes to the Gem.cs Script.
If you make the changes above and run the GemBuster game you should see something like the screenshot shown in the introduction of this post.
Now that you have completed the GemBuster game, to create an APK for your Android app in Unity, select “File” then “Build Settings”. Then click the “Build” button, choose a file name and location for the APK file and select “Save” and wait for the APK to be generated.