Book Image

Unity Certified Programmer: Exam Guide

By : Philip Walker
Book Image

Unity Certified Programmer: Exam Guide

By: Philip Walker

Overview of this book

Unity Certified Programmer is a global certification program by Unity for anyone looking to become a professional Unity developer. The official Unity programmer exam will not only validate your Unity knowledge and skills, but also enable you to be part of the Unity community. This study guide will start by building on your understanding of C# programming and take you through the process of downloading and installing Unity. You’ll understand how Unity works and get to grips with the core objectives of the Unity exam. As you advance, you’ll enhance your skills by creating an enjoyable side-scrolling shooter game that can be played within the Unity Editor or any recent Android mobile device. This Unity book will test your knowledge with self-assessment questions and help you take your skills to an advanced level by working with Unity tools such as the Animator, Particle Effects, Lighting, UI/UX, Scriptable Objects, and debugging. By the end of this book, you’ll have developed a solid understanding of the different tools in Unity and understand how to create impressive Unity applications by making the most of its toolset.
Table of Contents (17 chapters)
14
Full Unity Programmer Mock Exam

Setting up our Unity project

Things can get messy quickly in a project if we don't manage our files correctly by placing them into the allocated folders. If you want to structure your folders your own way, or during the book you decide to stray away from how I'm doing it, that's also fine. Just try and be conscious of your future self or other people working on this project when it comes to finding and organizing files.

Open the project up if you haven't already and create the following folders:

  1. Model contains 3D models (player ship, enemies, bullets, and so on).
  2. Prefab holds instances of game objects (these are created within Unity).
  3. Scene stores our first-level scene as well as other levels.
  4. Script contains all of our code.
  5. Material stores our game object materials.
You should know what a prefab is, as it's one of the main parts of what makes Unity so quick and easy to use. However, if you don't: it's typically your game object with its settings and components stored in an instance. You can store your game objects in your Project window as prefabs by dragging the game object from the Hierarchy window. A blue box icon will be generated following the game object's name, and if you select the prefab in the Project window, its Inspector window details will show all its stored values. If you would like to know more about prefabs, you can check out the documentation at https://docs.unity3d.com/Manual/Prefabs.html.

The following screenshot shows you how to create these folders:

Follow the steps given below:

  1. Within our Prefab folder, create another two folders, Enemies and Player.
  2. Inside the Script folder, create a folder called ScriptableObject.
  3. Create a folder in the Assets folder called Resources, and move our Model, Prefab, Script, and Material folders into it. The following screenshot shows what our folder structure should look like now:

Resources is a special folder that Unity recognizes. It will allow us to load assets while the game is running. For more information about the Resources folder, check the documentation at https://docs.unity3d.com/Manual/BestPracticeUnderstandingPerformanceInUnity6.html.

Provided in the Technical requirements section is the download link for the GitHub repository of this chapter. Once downloaded, double-click the Chapter2.unitypackage file and we will be given a list of assets to import into our Unity project:

  • Player_ship.fbx
  • enemy_wave.fbx

The following screenshot shows the import window of the assets we are about to bring into our project:

Make sure all assets are ticked and click the Import button in the bottom-right corner of the window. We can now move on to organizing our files and folders in the Project window in the next section.

Creating prefabs

In this section, we going to create three prefabs: the player, the player's bullet, and the enemy. These prefabs will hold components, settings, and other property values for our game that we can instantiate throughout our game.

Let's start with making our player_ship.fbx file into a prefab instance by doing the following.

Sometimes, when importing any three-dimensional file, each file may contain extra data that we might not need. For example, our player_ship model comes with its own material and animation properties. We don't require any of these, so let's remove these properties before continuing to import our models fully into our Unity project.

To remove the Animation and Material properties from our player_ship model, we need to do the following:

  1. In the Project window, navigate to Assets/Resources/Model and select the player_ship file.
  2. In the Inspector window, select the Materials button.
  3. Untick the Import Materials box, then click the Apply button.
  4. Now click the Animation button next to the Materials button.
  5. Untick the Import Animation checkbox, followed by clicking the Apply button.
  6. Select the Rig button next to the Animation button.
  7. Select the current value in the AnimationType drop-down menu and select None, followed by the Apply button.
  8. That's all of our Material and Animation information removed from our player_ship model.
Throughout the book whenever we select a three-dimensional model, make sure to run through the same process, as we will not require imported extras such as the ones we just removed. This means I would like you now to repeat the process we have just gone through with the enemy_wave.fbx model.

Let's continue preparing our player_ship model for our game:

  1. Click and drag the player_ship from Assets/Resources/Model into the Hierarchy window.
  2. Select the player_ship in the Hierarchy window and set its name and Transform properties to the following values:
    • Game Object name: player_ship.
    • Tag: Player (easier to detect when colliding with enemies or other collisions).
    • Transform: All values set to zero apart from the Scale thatis set to 1 on all axes.

The following screenshot shows the player_ship values in the Inspector window:

  1. Click and drag the player_ship from the Hierarchy window into the Assets/Resources/Prefab/Player folder.

Notice the player_ship in the Hierarchy window has turned blue, which means it has become a prefab.

  1. Delete the player_ship from the Hierarchy window.

We are going to use a similar process to create our enemy_wave prefab, but we will also need to create its own name tag because there isn't an Enemy tag... yet.

Enemy prefab and custom tags

In this section, we are going to create an enemy_wave prefab along with a custom tag. The tag will be used to identify and categorize all related enemies under one tag.

To create an enemy_wave prefab and custom name tag, follow these instructions:

  1. In the Project window, drag the enemy_wave.fbx file from Assets/Resources/Model into the Hierarchy window.
  2. With the enemy_wave file selected in the Hierarchy window, update the following values in the Inspector window:
    • Game Object name: enemy_wave.
    • Transform: All values set to zero apart from the Scale, which is set to 1 on all axes:

Now let's create a new tag for the enemy_wave game object by doing the following:

  1. Choose the Untagged parameter in the Inspector window.
  2. From the Tag drop-down menu, select Add Tag....
  3. The Inspector window will now show the Tags & Layers window.
  4. Click the + to add a new tag, as circled in the following screenshot.
  5. Enter Enemy in the pop-up window, as shown in the following screenshot, then click the Save button:

  1. Back in the Hierarchy window, select the enemy_wave game object to bring back our Inspector window details.
  2. Click the Untagged parameter again.
  3. We can now see Enemy in our drop-down list, so select it.
  4. Drag the enemy_wave game object from the Hierarchy window into Assets/Resources/Prefab/Enemies.

We now move on to our third prefab creation – the player's bullet. But this time, we won't import a three-dimensional model – we are going to create one in the Unity editor, then create a prefab from it in the next section.

Creating the player's bullet prefab

Next, we are going to create the visuals for the player's bullet in the Unity editor. We will make a blue sphere and give it a surrounding light source. Let's start by creating a three-dimensional sphere game object.

In the Hierarchy window, right-click and from the drop-down list select 3D Object | Sphere.

With the newly created Sphere in the Hierarchy window still selected, make the following changes to the Inspector window:

  • Change the game object name from Sphere to player_bullet.
  • Change Tag from Untagged to Player. The tag name makes it easier to identify later on in the chapter.
  • The Transform parameters are all set to zero, apart from the Scale of the bullets, which should be slightly larger, with a Scale of 2 on all axes.

The following screenshot shows all three changes:

Next, we will give the player_bullet game object a new blue material.

Creating and applying a material to the player's bullet

In this section, we will be creating a simple unlit material that will not take up much of the device's performance thanks to the simplicity of the material. To create a basic material and apply it to the player_bullet object, do the following:

  1. In the Project window, navigate to the Assets/Resources/Material folder.
  2. Inside the Material folder, make a new folder (the same way we did in the Setting up our Unity project section) and name the folder Player. That way, any material related to the player can be stored inside.
  3. Double click the newly created Player folder and right-click in the Project window (in the open space in the right section of the window) again and, from the drop-down list, select Create | Material.

A new material file will be made. Rename it to player_bullet.

  1. Select the player_bullet material and, in the Inspector window, change the material from a Standard shader to Unlit | Color by following the three steps in the following screenshot:

The Inspector window will remove the majority of the properties and strip the material back to something simpler and easier to perform on any device.

  1. Still, in the Inspector window, click the Main Color swatch parameter and change it to a cyan color with the following values: R: 0, G: 190, B: 255, and A: 255.

We have created and calibrated our player's bullet, so now, we can apply the material to the player_bullet prefab by doing the following:

  1. Select the player_bullet prefab in the following location of the Project window: Assets/Resources/Prefab/Player.
  2. In the Inspector window, under the Mesh Renderer component, click the small round radio button to the right of the Element 0 parameter and type player_bullet in the drop-down list until you see the material, then select it.

The following screenshot shows the player_bullet prefab's Mesh Renderer component updated to our new unlit material:

In Chapter 4, Applying Art, Animation, and Particles, we will return to materials and art in general, which will be of note if you found this interesting. We will also play around with particle systems to create a fleet of stars rushing past the player's ship.

The last component we will add to our player's bullet is a surrounding light to give our bullet an energy glow.

Adding a light to the player's bullet

In this section, we will be adding a light component to the player's bullet to hide the impression that all that we are doing is firing spheres. It will also introduce us to Unity's point light, which acts as a glowing ball.

To add and customize a ball of light to the player's bullet, we need to do the following:

  1. In the Project window, navigate to the Assets/Resources/Prefab/Player folder and select the player_bullet prefab.
  2. In the Inspector at the bottom of the components listed, click the Add Component button and type Light from the drop-down list.

The player_bullet prefab will now have a Light component attached to it. We just need to change three property values to make the light suit the game object more.

  1. Change the following property values in the player_bullet file's Light component:
    • Range: 50
    • Color: R: 0, G: 190, B: 255, A: 255
    • Intensity: 20

The following screenshot shows the Light component after the values have been updated:

Before moving onto the next section, because we have taken an existing prefab and added a material and a light component, we need to click the Apply button to confirm the new changes.

  1. The following screenshot shows the Apply button in the top-right corner of the Inspector window for our player_bullet prefab:

  1. Finally, delete the player_bullet from the Hierarchy.

In the next section, we will continue to update our three prefabs by applying Unity's own physics system, the Rigidbody component, to help detect collisions.

Adding Rigidbody components and fixing game objects

Because this game involves collisions with game objects, we need to apply collision detection to the player, the player's bullets, and the enemy. Unity offers a range of different shapes to wrap around a game object that functions as an invisible shield; we can set our code to react to contact being made with the shield.

Before we add colliders to the player and enemy game objects (the Sphere game object automatically comes with a collider), we need to add a Unity component called a Rigidbody. If a game object is going to collide with another at least one other game object, it requires a Rigidbody component; Rigidbody components can affect a game object's mass, gravity, drag, constraints, and more. If you would like to know more about Rigidbody components, check out the documentation at https://docs.unity3d.com/Manual/class-Rigidbody.html.

Unity has other physics types apart from the collider. Joints also require the Rigidbody system, and Joints come in different forms, such as Hinge, Spring, and others.
These Joints will simulate at a fixed point; for example, the HingeJoint would be good at making a door swing back and forth around a door hinge's pivot point.
If you would like to know more about joints, check the documentation at https://docs.unity3d.com/Manual/Joints.html.

Let's add the RigidBody component to the player_ship and player_bullet prefabs:

  1. In the Project window, navigate to the Resources | Prefab | Player.
  2. Hold Ctrl (command on Mac) and click on the player_ship and player_bulletfiles.
  3. In the Inspector window, click the Add Component button.
  4. From the drop-down menu, type Rigidbody.
  5. Select Rigidbody (not Rigidbody 2D).
  6. The Rigidbody component has now been assigned to our two game objects.
  7. With the two game objects still selected in the Inspector window, under Rigidbody, make sure the Gravity checkbox isn't ticked. If it were, our game objects would begin to sink into the scene while the game is being played.

Now we can add colliders to our player_ship and enemy_wave game objects (our player_bullet already has a SphereCollider). We will be adding a SphereCollider to our game objects because it's the cheapest collider to use relative to performance costs:

  1. Click and drag the player_ship prefab from the Project window location of Assets/Resources/Prefab/Player into the Hierarchy window.
  2. With the player_ship still selected in the Hierarchy window, click the Add Component button in the Inspector window and type Sphere Collider into the drop-down menu.
  3. As soon as you see SphereCollider in the list, click it to add it to the player_ship game object.

You will notice a green wireframe around the player_ship in the Scene window (with the player_ship still selected in the Hierarchy window, hover your mouse in the Scene window and press F on the keyboard to zoom in on the ship if you can't see it). This is the player_ship collider that will be used to detect hits. It may be too big for the purpose of a hitbox, so let's reduce its size.

  1. With the player_ship prefab still selected in the Hierarchy window, alter the Radius of the SphereCollider component to 0.3 in the Inspector window, as shown in the following screenshot:

  1. Also, while we still have the player_ship prefab selected, check the Is Trigger box as shown in the previous screenshot. This will make it so the player_ship prefab looks for another collider without causing any form of potential physics collision.
  2. Click Apply in the top-right corner of the Inspector window to update the modifications we've made to our prefab with its Rigidbody and SphereCollider component.
  3. We can now select the player_ship prefab in the Hierarchy window and press Delete on our keyboard as we no longer need it in our Scene.

We now need to apply the same methodology to our player_bulletSphereCollider component:

  1. In the Project window, click and drag the player_bullet prefab from Assets/Prefab/Player into the Hierarchy window.
  2. Check the Is Trigger box and adjust the Radius in the SphereCollider component in the Inspector window.
  3. Click Apply in the top-right corner of the Inspector window to confirm the player_bullet changes and delete the player_bullet prefab from the Hierarchy window.

The last game object we need to update is the enemy_wave prefab. We have already covered the steps with the player_ship and player_bullet prefabs so it's not ideal to repeat the instructions in full; however, we need to do the following:

  1. As a short brief, I want you to drag and drop the enemy_wave prefab from its location at Assets/Resources/Prefab/Enemiesin the Project window.
  2. Add a SphereCollider component to the enemy_wave prefab in the Inspector window.
  3. Adjust the SphereCollider component so Is Trigger is checked and the Radius fits around the enemy_wave prefab with correct proportions, as we did with player_ship.
  4. The enemy_wave prefab doesn't require a Rigidbody component, as it will be colliding with relevant game objects that hold one themselves.
  5. Finally, Apply the prefab changes and remove the enemy_wave prefab from the Hierarchy window.

Use the following screenshot as a reference for the preceding mini brief and if you get stuck, use the previous steps that we discussed in this section:

Hopefully, that went well for you. If you get stuck at any point, refer to the Packt/Chapter2/Complete folder containing all the completed files to check them out and compare.

Before moving on, note that if a game object is pink, like our enemy_wave object in the previous screenshot, it simply means that it doesn't have a material attached. In other cases, it can also mean there is something wrong with the shader attached to the material.

We can fix this pink issue by doing the following:

  1. In the Project window, navigate to Assets/Resources/Prefab/Enemies/enemy_wave.
  2. Expand the enemy_wave game object to show the two game objects attached.
  3. Select the first game object titled enemy_wave_core.
  4. In the Inspector window, select the small remote circle next to the Element 0 parameter in the Mesh Renderer component (denoted by 1 in the following screenshot), then select Default-Material(denoted by 2) from the drop-down list, as shown in the following screenshot:

  1. Follow the same steps for its sibling game object, enemy_wave_ring.

The enemy_wave object will now have a default material applied.

If a game object requires a component such asRigidbody, we can place, above the class name, what is effectively a reminder to the script that the game object needs:

[RequireComponent(typeof(Rigidbody))]

If the game object doesn't have the component, the script will create one, and if we try to remove the Rigidbody component, we will receive a message in the Unity editor that it is a required component.

If you would like to know more about the RequireComponent attribute, check the documentation at https://docs.unity3d.com/ScriptReference/RequireComponent.html.

So, now we have our colliders and Rigidbody components applied to our game objects. This gives us the ability to create a reaction when colliders come into contact with each other.

Because we are starting to build up our project, let's quickly discuss saving our scenes, projects, and more.

Saving and publishing our work

It's easy to get stuck into our project, but as a brief reminder, save and publish your work with Unity Collaborate as often as possible. That way, if anything bad happens, you can always revert back.

Because we have created and saved our testLevel scene from the previous chapter, we can also add this scene to the Build Settings window. The reason for this is so that Unity is aware of what scenes we want toinclude in our project. It is also a requirement when it comes to packaging up our game as a build for deployment.

To add our scene to Build Settings, do the following:

  1. At the top of the Unity editor, click File | Build Settings. The Build Settings window will appear.
  2. Click the Add Open Scenes button to add the testLevel scene.
  3. The following screenshot shows the Add Open Scenes button circled, as well as an arrow pointing to the number index of our testLevel scene. When we add more scenes later, each scene will be numbered:

  1. Close the Build Settings window. We will come back to this when we have more scenes to add in the next chapter.
  2. It's a good habit to save the project by clicking File | Save Project.
Also, if you are a keen user of Collaborate, this is also a good time to publish (push) your work to the cloud. The following screenshot shows the top Collab button being clicked, followed byPublish now!to push the work into the cloud:

The end of each section, in this chapter and others, is a good time to save and publish your work. I won't remind you too often, but it's good to get into the habit.

Let's now continue with setting up our scene camera in the Unity editor.

Setting up our camera

For our side-scrolling shooter game Killer Wave, we need control over a camera to display the aspect ratio and visible depth of the scene, and to make sure we show the correct amount of our game's environment.

Let's get started and decide on the screen ratio of our game. We'll create our own resolution, which will be fairly common across most platforms.

To change the Game window's screen ratio to a custom aspect, do the following:

  1. Click the current aspect ratio under the Game window tab and select the + symbol.
  2. Enter the custom aspect ratio values shown in the following screenshot.
  3. Click OK once done, and select the 1080 resolution we have just made:

It is good to be aware of the need to make our game's artwork support (or to give it the scope to extend to) as many screen ratios as possible, especially if we ever wanted to make a game for portable devices such as tablets or mobile phones. This is because nearly every major brand of phone and tablet comes in different ratio sizes, and we don't want to start squashing and squeezing our content as it won't look right. It's also possible that our small mobile games will become successful and could laterbe ported to a console or PC. If that's the case, we need to make it so the game screen supports these ratios too. The main point to take from all of this is that we are targeting our game to cover all possible common screen ratios. The more platforms (consoles, portable devices, and so on) we can cover with flexible screen ratios, the easier it will be to extend our game out to those devices without requiring extra work. We explain more about screen size ratios inChapter 8,Adding Custom Fonts and UI, andChapter 9, Creating a 2D Shop Interface and In-Game HUD, where we discuss UI display settings. Additionally, in Chapter 13,Effects, Testing, Performance, and Alt Controls, we explain how to display our game screen on a raw image component.

Before we continue any further with our project, it's probably a good time to confirm our understanding of Unity's own UI layout. The following screenshot shows the Unity editor, where I have outlined and labeled the relevant windows:

Typically, the Unity editor window is made up of five main windows:

  • Scene: This is our two-/three-dimensional workspace.
  • Game: This window is what the end user will see. By default, the Game tab shares the same space as the Scene window.
  • Hierarchy: All game objects in our scene will be listed here.
  • Inspector: When an object is selected, information about it will be displayed here.
  • Project: This is our Unity project folder. Consider it a structure of files and folders that we can use in our game.
To drag each window around individually, left-click and drag the name of the tab and it will then snap into different locations.

My Game window is set to 1080 and because I don't have the luxury of a second screen, I've clicked its name tab (Game) and pulled it down in the bottom-right corner. The window is small, but as you can see at the top of the Game window, the scale is set to 1x, which means I have a full picture; nothing is hidden or cut out of view.

To check we have the main camera's Transform properties reset to its default settings, make sure its Position, Rotation, and Scale are all set to 0. We can also reset the Transform option as follows:

  1. With the main camera selected in the Hierarchy window, click the silver cog in the top-right corner of the Transform panel in the Inspector window, as shown in the following screenshot:

  1. When the dropdown appears, click Reset.

Continuing on with setting up our main camera, let's get rid of the landscape background in our Scene/Game window by changing its Background setting:

  1. Click the Main Camera in the Hierarchy window.
  2. In the Inspector window, we have the Camera component with a property called Clear Flags. Click the Skybox value.
  3. A dropdown will appear. Click Solid Color, as shown in the following screenshot:

  1. We will now be presented with a blue background, which is less distracting.
  2. If you don't like blue, you can change it to any color in the Background property. I'm going to make mine black by changing the Red, Green, Blue, and Alpha (RGBA) values to R: 0, G:0, B:0, and A:255, as shown in the following screenshot:

Great, now let's move on to coding these properties for our main camera.

Updating our camera properties via a script

We now have our main camera's behavior set in our Scene. Next, we need to code this into a script so that whenever a scene is loaded, Unity will read the script and understand how the main camera should be set up.

Observing our framework again, let's see where the camera script should be placed:

As you can see in the diagram, there is no reference to the camera, so should we make a script to support this? Arguably the only reason to make a script based on the camera would be if the camera had a complex purpose filled with multiple properties and functions. The camera in our game, however, is put in place when the game starts. Later on, on the third level, the camera will move from left to right with a simple component script, but it doesn't hold any other complexity. It would, therefore, be more ideal to use theGameManager, as it only takes up a small role. If the game became bigger and the camera took on more of a role, then this might justify the camera having a class of its own. Others might disagree based on personal preference, but this is the approach we'll take.

Let's make the GameManager script as follows:

  1. Create a script in the same way that we created a folder. Right-click the open space area in the Project window, and a dropdown will appear. Click Create | C# Script, as follows:

  1. The script appears with the title NewBehaviourScript. We don't want to call it that, so type (in camel case) GameManager.
What's camel casing?
Camel casing is a way to avoid spacing between words. This is fairly common with programming as spaces are typically not welcomed for various reasons. Each new word starts with a capital letter, so in this case, the M in GameManager is the hump of the camel. However, variables typically start with lowercase, as you will see shortly.

We now have our GameManager script. Notice how Unity is trying to be helpful by changing the icon to a silver cog because what we are doing is a recognized method with Unity:

As we did with placing our three-dimensional models into the Model folder, move the GameManager into the Script folder.

Good. Now, before we open our script to code in it, we need to attach it to a game object in our scene so that when the scene runs, the script attached to the game object also runs.

To create our GameManager game object, we need to do the following:

  1. Right-click in an open space in the Hierarchy window.
  2. From the drop-down menu, select Create Empty.
  3. Right-click the newly created game object and select Rename from the drop-down menu.
  4. Rename this game object to GameManager.
  5. Finally, with the GameManager game object still selected, click the Add Component button in the far-right Inspector window.
  6. Type GameManager from the drop-down menu until you see the GameManager script, and select it.
Whenever we make an empty game object, we must be sure that all of its Transform property values are reset to their default values unless we are specifically changing them.

To reset a game object's Transform value, make sure the game object we are resetting is selected. Click the metal cog in the top-right corner of the Inspector window, then select Reset.

Double-click the GameManager script to open it up in your IDE (Visual Studio or whatever IDE you use), then proceed as follows:

  1. Inside the GameManager script, we will be faced with the UnityEngine library being imported into our script to add extra functionality to Unity's own components:
          using UnityEngine;

public class GameManager : MonoBehaviour
{

Also in the preceding code, we have the name of our script along with MonoBehaviour being inherited yet again to add more functionality to our script. MonoBehaviour is also required if the game object that attaches to this script needs to be used in the Unity editor.

Let's start adding some of our own code into our GameManager script.

  1. Create an empty method, CameraSetup, and then run this method in the Start function:
    void Start()
{
CameraSetup();
}
void CameraSetup()
{

}
  1. Inside the CameraSetup method, add a reference to the camera and set the position and angle of the camera to zero apart from its z axis. We'll set Z to -300, which will move the camera back and ensure all game objects are in the shot:
GameObject gameCamera =
GameObject.FindGameObjectWithTag("MainCamera");

//Camera Transform
gameCamera.transform.position = new Vector3(0,0,-300);
gameCamera.transform.eulerAngles = new Vector3(0,0,0);
  1. Next, we will change the properties of the camera within our CameraSetup method:
 //Camera Properties
gameCamera.GetComponent<Camera>().clearFlags =
CameraClearFlags.SolidColor;
gameCamera.GetComponent<Camera>().backgroundColor =
new Color32(0,0,0,255);
}

This does the following:

  • Removes the sky background and replaces it with a solid color
  • Changes the solid color from the default blue to black
  1. Finally, save the script.

Now you should have something like this:

If you would like to change other settings relating to the camera, you can find out about them at https://docs.unity3d.com/ScriptReference/Camera.html.

Press the Play button in the upper middle of the editor window, or by using the shortcut Ctrl + P (command + P on the Mac). The following screenshot shows where the Play button is located:

With the scene in play mode, we can now check out the Main Camera game object's properties by doing the following:

  1. In the Hierarchy window, select Main Camera.

Observe the Inspector window in the next screenshot to see the following changes our script has made.

  1. In the Transform component of the Inspector window, we can see the Position and Rotation properties are set to the same values set in our script (denoted by 1 in the following screenshot).
  2. In the Camera component of the Inspector window, we can see the Clear Flags and Background values are also set to the same values set in our script (denoted by 2i and 2ii).

The following screenshot shows the Main Camera component properties being updated in Play mode:

Now, hopefully, our properties should be the same as what we have scripted (with no errors). If not, you will likely have an error message in the Console window. If there is an error, it will likely tell you what line the error is on. You can also double-click the error, and it will take you to the line the error is on.

To double-check everything has worked, change the Position and Rotation of the camera in the editor and then press the Play button. The properties for the camera should now be set to our script's Position and Rotation properties.

At this point, while the editor is still playing, we could also make a prefab of the camera:

  1. Click and drag the Camera from the Hierarchy window down into the Project window, and we will generate a blue cube with the camera's name or an empty icon. Depending on the scale of our icons, the size of the icon can be altered by moving the slider shown in the following screenshot:

  1. Move this camera prefab into the Prefab folder.

You might be thinking, why didn't we just make a prefab of the camera in the first place instead of fiddling with its property settings in code? However, two key things are important here: firstly, we are studying for an exam that is likely to cover such properties; and secondly, you now know how to change these settings dynamically through code.

Another benefit to scripting Unity's components is that we can sometimes be offered more functionality than what is displayed in the Editor. For example, the Camera component has a layerCullDistances property that is only accessible via scripting. This can offer functionality such as skipping the rendering of smaller game objects in the far distance to increase a game's performance.

To read up more on layerCullDistances, check the documentation at https://docs.unity3d.com/ScriptReference/Camera-layerCullDistances.html.

This brings this section to a close. So far, we have covered the following:

  • Setting up a ratio for our game camera
  • Setting up our Unity editor with individual windows
  • Changing the properties of our Camera component in the Unity editor
  • Repeating the changes we made to our camera in the GameManager script
  • Adding our GameManager script to our scene as a game object

As a programmer, the importance of being able to understand and change the settings in the Unity editor (but to also be able to do the same in code) can be expanded to other components that are in the editor. This is what we will do next, with a focus on directional light.

Setting up our light

As a default setup, each scene comes with a directional light, and currently, this is all we need to get going; ideally, we want the scene to be well lit.

With the directional light already present in the scene as the default light, select it in the Hierarchy window. In the Inspector window, set the Directional Light's TransformRotation values to the following:

X: 50, Y:-30, Z:0

When we put our player ship into the scene, this will light it up well, as shown in the following screenshot:

Unity provides three different types of real-time lights. As well as the directional light we mentioned, it also provides a point light, which is like a 360° glow that we will cover in Chapter 4, Applying Art, Animation, and Particles. The third type of light is a spotlight or as Unity refers to it, a spot. The spot can also have masks applied so it can project images known as cookies.

For more information about the three types of lights, check out https://docs.unity3d.com/Manual/Lighting.html.

We can now make sure these settings stay in place by adding them to the GameManager script. We can also alter the light's color.

Updating our light properties via a script

In the GameManager, we will set the TransformRotation values and change the color tint from a light yellow to a cold blue:

  1. Open the GameManager script and enter the following method:
void LightSetup()
{
GameObject dirLight = GameObject.Find("Directional Light");
dirLight.transform.eulerAngles = new Vector3(50,-30,0);
dirLight.GetComponent<Light>().color =
new Color32(152,204,255,255);
}
  1. Add LightSetup(); in the scope of the Start function.
  2. Save the script.

The LightSetup method does three things:

  • It grabs the light from the scene and stores it as a reference.
  • It sets the rotation of the light with EulerAngles.
  • Finally, it changes the light's color.
eulerAngles allows us to give Vector3 coordinates instead of Quaternion values. eulerAngles makes it so rotations are less complicated to work with. More information about eulerAngles can be found at https://docs.unity3d.com/ScriptReference/Transform-eulerAngles.html.

That's all we need to do with our light. As with the camera, we can access the light and change its properties via a script.

We have become familiar with our light by changing its settings in the Unity editor and the GameManager script. Next, we will set up our interface for the majority of our game objects.