Chapter 20: Building the Project – Hands-On Unity 2020 Game Development

Chapter 20: Building the Project

So, we have reached a point where the game is mature enough to test it with real people. The problem is that we can't pretend people will install Unity, open a project, and hit Play. They want to receive a nice executable file to double-click and play right away. In this chapter, we are going to discuss how we can convert our project into an easy-to-share executable format.

In this chapter, we will examine the following build concepts:

  • Building a project
  • Debugging the build

Building a project

In software development (including video games), the result of taking the source files of our project and converting them into an executable format is called Build. The generated executable files are optimized to get the maximum performance possible. We can't get performance while editing the game due to the changing nature of a project. It would be time-consuming to prepare the assets in their final form while editing the game. Also, the generated files have a difficult-to-read format. They won't have the textures, audios, and source code files just there for the user to look at. They will be formatted in custom file structures, so in a way, it's protected from users stealing them.

Important note

Actually, there are several tools to extract source files from video games, especially from a widely used engine such as Unity. You can extract assets such as textures and 3D models, and there are even programs that extract those assets directly from the VRAM, so we cannot guarantee that the assets won't be used outside the game. In the end, users have the data of those assets in their disks.

The build process is pretty simple when you target desktop platforms such as PC, Mac, or Linux, but there are a few settings we need to keep in mind before building. The first configuration we are going to see is the scenes list. We have already discussed this, but it's a good moment to remember that it is important to set the first element of this list to the Scene that will be loaded first. Remember, you can do this by going to File | Build Settings and dragging your desired starter scene to the top of the list. In our case, we defined the Game scene as the first scene, but in a real game, it would be ideal to create a Main Menu scene using UI and some graphics:

Figure 20.1 – The Scenes list order

Another setting you can change here is the target platform – the target operating system that the build will be created for. Usually, this is set for the same operating system you are developing on, but if you are, as an example, developing on a Mac, and you want to build for Windows, just set the Target Platform setting to Windows. That way, the result will be exe instead of app. You may see Android and iOS as other target platforms, but making mobile games requires other considerations that we are not going to discuss in this book:

Figure 20.2 – Target Platform

In the same window, you can click the Player Settings button at the bottom left, or just open the Edit | Project Settings window and click on the Player category to access the rest of the Build Settings. Unity calls the generated executable files the game Player. Here we have a set of configurations that will affect how the build or Player behaves, and here is a list of the basic ones:

  • Product Name: This is the name of the game in the window title bar and executable file.
  • Company Name: This is the name of the company that developed the game, which is used by Unity to create certain file paths and will be included in the executable information.
  • Default Icon: Here, you can select a texture to act as the executable icon.
  • Default Cursor: You can set a texture to replace the regular system cursor. If you do that, remember to set the Cursor Hotspot property to the pixel of the image you want the cursor to do the clicks.
  • Resolution and Presentation: Settings about how our game's resolution is going to be handled.
  • Resolution and Presentation | Default is Native Resolution: With this checked and when the game is running in full-screen mode, the resolution currently used in the system will be the one used by Unity. You can uncheck this and set your desired resolution.
  • Splash Image: Settings about the splash image the game will show after loading for the first time.
  • Splash Image | Show Splash Screen: This will enable a Unity splash screen that will display logos as an introduction to the game. If you have the Unity Pro license, you can uncheck this to create your custom splash screen, if you want to.
  • Splash Image | Logos List: Here, you can add a set of images that Unity will display when launching the game. If you are using Unity for free, you are forced to have the Unity logo displayed in this list.
  • Splash Image | Draw Mode: You can set this to All Sequential to show each logo, one after the other, or to Unity logo Below to show your custom introductory logos with the Unity logo always present below yours:

Figure 20.3 – Player settings

After configuring these settings as you wish, the next step is to do the actual build, which can be accomplished by hitting the Build button in the File | Build Settings window. This will ask you to set where you want the build files to be created. I recommend you create an empty folder on your desktop to have easy access to the result. Be patient—this process can take a while according to the size of the project:

Figure 20.4 – Building the game

Something that can fail here is having non-build compatible scripts—scripts that are intended to be executed only in the editor, mostly editor extensions. We haven't created any of those, so if you have an error message in the console after building, similar to the following screenshot, that can happen because of some script in some Asset Store package. In that case, just delete the files that are shown in the console before the Build Error message. If, by any chance, there is one of your scripts there, be sure you don't have any using UnityEditor; lines in any of your scripts. That would try to use the Editor namespace, the one that is not included in the build compilation to save space in the disk:

Figure 20.5 – Build errors

And that's pretty much everything you need to know. You have generated your game! Something to take into account is that every file that was created in the folder that you specified when building must be shared, not only the executable file. The Data folder contains all assets and is important to include when sharing the game in the case of Windows builds. For Linux and Mac builds, there is just one file generated (x86/x86_64 and app packages respectively):

Figure 20.6 – A Windows-generated folder

One last piece of advice—pay attention to the Script Build Only checkbox in the Build window. If you changed only code and want to test that change, check it and do the build. This will make the process go faster than a regular build. Just remember to uncheck this if you changed anything else in the editor because those changes won't be included if you have it checked.

Now that we have the build, you can test it by double-clicking the executable file. Now that you have tried your build, we can discuss how we use the same Debug and Profiling tools we used in the editor to test our build.

Debugging the build

In an ideal world, the editor and the build will behave the same, but sadly that isn't true. The editor is prepared to work in a fast-iteration mode. Code and assets have minimum processing prior to being used to make changes often and fast, so we can test our game easily. When the game is built, a series of optimizations and differences from the editor project will be applied to ensure the best performance we can get, but those differences can cause certain parts of the game to behave differently, making the profiling data of the player differ from the editor. That's why we are going to explore how we can debug and profile our game in the build.

In this section, we will examine the following Build Debugging concepts:

  • Debugging Code
  • Profiling Performance

Let's start discussing how to debug the code of a build.

Debugging code

As player code is compiled differently, we can get errors in the build that didn't happen in the editor, and we need to debug it somehow. We have two main ways to debug—by printing messages and through breakpoints. So, let's start with the first one, messages. If you ran your executable file, you may have noticed that there's no console available. It's just the Game view in fullscreen, which makes sense; we don't want to distract the user with annoying testing messages. Luckily, the messages are still being printed, but in a file, so we can just go to that file and look for them.

The location varies according to the operating system. In this list, you can find the possible locations:

  • Linux: ~/.config/unity3d/CompanyName/ProductName/Player.log
  • Mac: ~/Library/Logs/Company Name/Product Name/Player.log
  • Windows: C:\Users\username\AppData\LocalLow\CompanyName\ProductName\Player.log

In these paths, you must change CompanyName and ProductName with the values of the properties in the Player settings we set before, which are called the same, Company and Product Name. In Windows, you must replace username with the name of the Windows account you are executing the game in. Consider that the folders might be hidden, so enable the option to show hidden files in your operating system:

Figure 20.7 – Showing hidden files

Inside that folder, you will find a file called Player; you can open it with any text editor and look at the messages. In this case, I have used Windows, so the directory path looks like the following screenshot:

Figure 20.8 – Debugging directory

Aside from downloading any custom package from the Asset Store, there is a way to see the messages of the console directly in the game, at least the error messages—by creating a development build. This is a special build that allows extended debugging and profiling capabilities in exchange for not fully optimizing the code as the final build does, but it will be enough for general debugging. You can create this kind of build by just checking the Development Build checkbox in the File | Build Settings window:

Figure 20.9 – The Development Build checkbox

Remember that just the error messages will be displayed here, so a little trick you can do is to replace the print and Debug.Log function calls with Debug.LogError, which will also print the message in the console but with a red icon. Consider that this is not a good practice, so limit the usage of this kind of message for temporal debugging. For permanent logging, use the log file or find a custom debugging console for runtime in the Asset Store.

Remember that for Development Build to work you need to build the game again; luckily, the first build is the one that takes the most time, and the next will be faster. This time, you can just click the Build and Run button to do the build in the folder in which you did the previous build:

Figure 20.10 – Debugging error messages

In the next screenshot, you can see the error being displayed in the runtime:

Figure 20.11 – Error messages in a development build

Also, you can use regular breakpoints the same way as we explained in Chapter 13, Introduction to Unity Scripting with C#. Attaching the IDE to the player, it will show up in the list of targets. But for that to work, you must not only check Development Build in the Build window but also Script Debugging. Here, you have an additional option shown when that is checked that allows you to pause the entire game until a debugger is attached, the one called Wait for Managed Debugger. This is useful if you want to test something that happens immediately at the beginning and doesn't allow you enough time to attach the debugger:

Figure 20.12 – Enabling script debugging

We have another way to see the messages, but that will require the Profiler to work, so let's use this as an excuse to also discuss how to profile the editor.

Profiling performance

We are going to use the same tools as we saw in the previous chapter, but to profile the player this time. Luckily, the difference is minimal. As we did in the previous section, you need to build the player in Development mode, checking the Development Build checkbox in the Build window, and then the profilers should automatically detect it.

Let's start using the Profiler on the build by doing the following:

  1. Play the game through the build.
  2. Switch to Unity using Alt + Tab (command + tab on Mac).
  3. Open the Profiler.
  4. Click the menu that says Playmode and select the item that contains Player in it. Because I have used Windows, it says WindowsPlayer:

Figure 20.13 – Profiling the player

Notice that when you click a frame, the game won't stop like in the editor. If you want to focus your attention on the frames at a specific moment, you can click the record button (the red circle) to make the Profiler stop capturing data, so you can analyze the frames captured so far.

Also, you can see that when the Profiler is attached to the player, the console will also be attached, so you can see the logs directly in Unity. Consider that this version requires Unity to be opened, and we cannot expect our friends who are testing our game to have it. You might need to click on the Player button that appears on the Console and check Player Logging for this to work:

Figure 20.14 – Enabling Player Logging after attaching the Profiler

The Frame Debugger is also enabled to work with the player. You need to click the Editor button in the Frame Debugger and again, you will see the player in the list of possible debugging targets; after selecting it, hit Enable as usual. Consider that the preview of the Draw Calls won't be seen in the Game view but in the build itself. If you are running the game in full screen mode, you might need to switch back and forth between Unity and the build:

Figure 20.15 – Debugging the frames of our game's player

You may also run the game in Windowed mode, setting the Fullscreen Mode property in the Player settings to Windowed, and establishing a default resolution that is smaller than your desktop resolution, to have both Unity and the player visible:

Figure 20.16 – Enabling Windowed mode

Finally, Memory Profiler also supports profiling the Player, and as you might guess, you can just select the player in the list that is displayed when you click the first button of the top bar of the window and then click Capture Player:

Figure 20.17 – Taking memory snapshots of the player

And that is it. As you can see, Unity Profilers are designed to be easily integrated with the player. If you start to take data from them, you will see the difference compared to editor profiling, especially in Memory Profiler.

Summary

In this chapter, we saw how to create an executable version of the game and properly configure it so you can share it with not only your friends but potentially the world! We also discussed how to profile our build; remember that doing that will give us more accurate data than profiling the editor, so we can better improve the performance of our game.

But before doing that, let's discuss some final details. These are not Unity-related details, but game-related ones; things you need to consider before and after showing your game to people other than yourself or any person that saw your game while it was being developed. We will do this in the next chapter.