Unity 2020 By Example
上QQ阅读APP看书,第一时间看更新

Starting a level

This section covers many fundamental topics that will be useful not only for the remainder of this book, but for your career as a Unity developer:

  • In Creating a Scene, you'll be introduced to the space that will contain our level. I'll show you how to create a new scene and explain what is included in a scene by default.
  • Once we've created a new scene, we can start customizing the space by adding and positioning objects. In Adding a Floor Mesh, we add a floor object to the scene, which our character (which we'll add later) will be able to traverse.
  • With the first objects added, we'll take a moment to look at how we can customize their size and position in Transforming Objects.
  • Before we add additional objects to the scene, it is essential to be able to navigate around the scene view so you can place objects exactly where you want them. This is covered in Navigating the Scene.
  • Once we can navigate the scene, we will continue to add new features in Adding Level Features, including houses and a bridge. The houses will be positioned using a Unity feature called Vertex Snapping.
  • At this point, the level will look flat with minimal shadows and lighting. We'll improve this by enabling lighting and adding a sky to the game in Adding Lighting and a Skybox.

There's a lot to cover! So, let's jump right in and create the first scene of our game.

Creating a scene

A scene refers to a 3D space, the space-time of the game world—the place where things exist. Since all games happen in space and time, we'll need a scene for the coin collection game. In our game, a scene represents a level. The words scene and level can be used interchangeably here. In other games, you may find that a scene contains multiple levels, but in this book, we will limit each scene to one level.

To create a new scene, perform the following steps:

  1. Select File | New Scene from the application menu.
  2. Alternatively, press Ctrl + N on the keyboard.

When you do this, a new and empty scene is created. You can see a visualization or preview of the scene via the Scene tab, which occupies the largest part of the Unity interface:

Figure 1.14 – The Scene tab displays a preview of a 3D world

Important note

As shown in Figure 1.14, other tabs besides the scene are visible and available in Unity. These include a Game and a Console window; in some cases, there could be more as well. For now, we can ignore all the tabs except scene. The scene tab is designed for quick and easy previewing of a level during its construction.

Each new scene begins empty; well, almost empty. By default, each new scene begins with two objects; specifically, a light to illuminate any other objects that are added, and a camera to display and render the contents of the scene from a specific vantage point. You can view a complete list of all the objects existing in the scene using the Hierarchy panel, which is docked to the left-hand side of the Unity interface, as shown in Figure 1.15. This panel displays the name of every GameObject in the scene. In Unity, the word GameObject refers to a single, independent, and unique object that lives within the scene, whether visible or not. When a GameObject is first created, it only has a Transform component, which includes position, scale, and rotation fields (more on the Transform component in the Transforming objects section). To extend the functionality of GameObjects, you add components. Component-based architecture is one of the core tenants of Unity; as such, we'll be taking advantage of existing components and creating entirely new components in every project in this book. GameObjects and components are discussed further in the section entitled Improving the scene:

Figure 1.15 – The Hierarchy panel

Tip

You can also select objects in the scene by clicking on their name in the Hierarchy panel.

With the scene created, we can start building the environment by adding a traversable floor mesh.

Adding a floor mesh

Next, let's add a floor to the scene. After all, the player needs something to stand on! We could build a floor mesh from scratch using third-party modeling software, such as Maya, 3DS Max, or Blender. However, the Standard Asset package, which was imported earlier, conveniently contains floor meshes that we can use. These meshes are part of the Prototyping package.

To access them via the Project panel, follow these steps:

  1. Open the Standard Assets folder by double-clicking it and then accessing the Prototyping/Prefabs folder.
  2. From here, you can select objects and preview them in the Inspector window:

Figure 1.16 – The Standard Assets/Prototyping folder contains many meshes for quick scene building

Tip

You could also quickly add a floor to the scene by choosing GameObject | 3D Object | Plane from the application menu. However, this just adds a dull, gray floor, which isn't very interesting. Of course, you could change its appearance. As we'll see later, Unity lets you do this. However, for this tutorial, we'll use a specifically modeled floor mesh via the Standard Assets package from the Project panel.

The mesh named FloorPrototype64x01x64 (as shown in Figure 1.16) is suitable as a floor. To add this mesh to the scene, drag and drop the object from the Project panel to the scene view. Notice how the scene view changes to display the newly added mesh within the 3D space, and the mesh name also appears as a listing in the hierarchy panel:

Figure 1.17 – Dragging and dropping mesh assets from the Project panel to the Scene view will add them to the scene

The floor mesh asset from the project window has now been instantiated as a GameObject in the scene. This GameObject is a copy or clone of the mesh asset. The instance of the floor in the scene still depends on the floor asset in the Project panel. However, the asset does not depend on the instance. Deleting the floor in the scene will not delete the asset; but, if you remove the asset, you will invalidate the GameObject. You can also create additional floors in the scene by dragging and dropping the floor asset from the Project panel to the scene view.

Each time, a new instance of the floor is created in the scene as a separate and unique GameObject, although all the added instances will still depend on the single floor asset in the Project panel:

Figure 1.18 – Adding multiple instances of the floor mesh to the scene

We don't actually need the duplicate floor pieces. So, let's delete them. Just click on the duplicates in the scene view and then press Delete on the keyboard to remove them. Remember, you can also select and delete objects by clicking on their name in the hierarchy panel and pressing Delete. Either way, this leaves us with a single floor piece and a solid start to building our scene. One remaining problem, though, concerns the floor and its name. By looking carefully in the hierarchy panel, we can see that the floor name is FloorPrototype64x01x64. This name is long, obtuse, and unwieldy. We should change it to something more manageable and meaningful. This is not technically essential but is good practice in terms of keeping our work clean and organized. There are many ways to rename an object. One way is to first select it and then enter a new name in the name field in the Inspector window. I've renamed it to WorldFloor:

Figure 1.19 – Renaming the floor mesh

As you can see from Figure 1.19, there are a number of other variables you can change on the object. Just below the name field, you'll notice a Transform heading. It is here where you can change the Scale, Rotation, and Position of an object, which we will often want to, as when we add an object to the scene, it may not always have the correct size or be in the right place. We'll look at the Transform component in the next section.

Transforming objects

A scene with a floor mesh has been established, but this alone is not very interesting. We should add more varied objects, such as buildings, stairs, columns, and perhaps even more floor pieces. Otherwise, there would be no world for the player to explore. Before building on what we have got, however, let's make sure that the existing floor piece is centered at the world origin. Every point and location within a scene are uniquely identified by a coordinate, measured as an (X, Y, Z) offset from the world center (origin).

The current position for the selected object is always visible in the Inspector panel. In fact, the Position, Rotation, and Scale of an object are grouped together under a category (component) called Transform:

  • Position indicates how far an object should be moved in three axes from the world center.
  • Rotation indicates how much an object should be turned or rotated around its central axes.
  • Scale indicates how much an object should be shrunk or expanded to smaller or larger sizes. A default scale of 1 means that an object should appear at normal size, 2 means twice the size, 0.5 means half the size, and so on.

Together, the position, rotation and scale of an object constitute its transformation.

To change the position of the selected object, you can simply type new values in the X, Y, and Z fields for position. To move an object to the world center, simply enter (0, 0, 0), as shown in Figure 1.20:

Figure 1.20 – Centering an object to the world origin

This will move the objects pivot point to the world origin. The pivot point is the designated position around which the object will rotate and scale. For the floor mesh, the pivot point is set to the center of the mesh, so when it is positioned at the world center, it will be this point that resides at the location (0, 0, 0).

Setting the position of an object, as we've done here, by typing numerical values, is acceptable and appropriate for the specifying of exact positions. However, it's often more intuitive to move objects using the mouse. To do this, let's add a second floor piece and position it away from the first. Drag and drop a floor piece from the Project panel to the scene to create a second floor GameObject. Then, click on the new floor piece to select it and switch to the Move Tool. To do this, press W on the keyboard or click on the Move Tool icon from the toolbar at the top of the editor interface. The move tool allows you to reposition objects in the scene:

Figure 1.21 – Accessing the move tool

When the translate tool is active and an object is selected, a gizmo appears centered on the object. The translate gizmo appears in the scene view as three colored perpendicular axes: red, green, and blue, corresponding to X, Y, and Z, respectively.

To move an object, hover your cursor over one of the three axes (or planes between axes), and then click and hold the mouse while moving it to slide the object in that direction. You can repeat this process to ensure that your objects are positioned where you need them to be. Use the translate tool to move the second floor piece away from the first, as shown in Figure 1.22:

Figure 1.22 – Translate an object using the translate gizmo

You can also rotate and scale objects using the mouse, as with translate. Press E to access the rotate tool or R to access the scale tool, or you can activate these tools using their respective toolbar icons from the top of the editor. Other available tools are the rect tool and the combined tool, which allow you to move, rotate, or scale an object using one tool. When these tools are activated, a gizmo appears centered on the object, and you can click and drag the mouse over each specific axis to rotate or scale objects as needed:

Figure 1.23 – Accessing the tools

Being able to translate, rotate, and scale objects quickly through mouse and keyboard combinations is very important when working in Unity. For this reason, make using the keyboard shortcuts a habit, as opposed to accessing the tools continually from the toolbar.

Navigating the scene

In addition to moving, rotating, and scaling objects, you'll frequently need to move around yourself in the scene view in order to see the world from different positions, angles, and perspectives. This means that you'll frequently need to reposition the scene preview camera in the world. You'll want to zoom in and zoom out of the world to get a better view of objects and change your viewing angle to see how objects align and fit together properly. To do this, you'll need to make extensive use of both the keyboard and mouse together.

To zoom closer or further from the object you're looking at, simply scroll the mouse wheel up or down—up zooms in and down zooms out.

To pan the scene view left or right, or up or down, hold down the middle mouse button while moving the mouse in the appropriate direction. Alternatively, you can access the hand tool from the application toolbar or by pressing Q on the keyboard, and then clicking and dragging in the scene view while the tool is active. Pan does not zoom in or out, but slides the scene camera left and right, or up and down.

Sometimes, while building levels, you'll lose sight entirely of the object that you need. In this case, you'll often want to shift the viewport camera to focus on that specific object. To do this automatically, select the object by clicking on its name in the hierarchy panel, and then press the F key on the keyboard. Alternatively, you can double-click its name in the hierarchy panel.

After framing an object, you'll often want to rotate around it in order to quickly and easily view it from all important angles. To achieve this, hold down the Alt key on the keyboard while clicking and dragging the mouse to rotate the view.

Lastly, it's helpful to navigate a level in the scene view using first-person controls, that is, controls that mimic how first-person games are played. This helps you experience the scene at a more personal and immersive level. To do this, hold down the right mouse button and use the WASD keys on the keyboard to control forward, backward, and strafing movements. Movement of the mouse controls head orientation. You can also hold down the Shift key while moving to increase movement speed.

The great thing about learning the versatile transformation and navigation controls is that, on understanding them, you can move and orient practically any object in any way, and you can view the world from almost any position and angle. Being able to do this is critically important in building quality levels quickly. All of these controls, along with some others that we'll soon see, will be used frequently throughout this book to create scenes and other content in Unity. With these controls in mind, we'll continue to build the environment by adding additional level features, including houses and a bridge to connect the two floor meshes.

Adding level features

Now that we've seen how to transform objects and navigate the scene viewport successfully, let's proceed to complete our first level for the coin collection game:

  1. Separate the two floor meshes, leaving a gap between them that we'll fix shortly by creating a bridge, which will allow the player to move between the spaces like islands. Use the translate tool (W) to move the objects around:

    Figure 1.24 – Separating the floor meshes into islands

    Tip

    If you want to create more floor objects, you can use the method that we've seen already by dragging and dropping the mesh asset in the Project panel in the scene viewport. Alternatively, you can duplicate the selected object in the viewport by pressing Ctrl + D on the keyboard. Both methods produce the same result.

  2. Then add some props and obstacles to the scene. Drag and drop the house prefab onto the floor. The house object (HousePrototype16x16x24) is found in the Assets/Standard Assets/Prototyping/Prefabs folder:

Figure 1.25 – Adding house props to the scene

On dragging and dropping the house in the scene, it may align to the floor nicely with the bottom against the floor, or it may not. If it does, that's splendid and great luck! However, we shouldn't rely on luck every time because we're professional game developers! Thankfully, we can make any two mesh objects align easily in Unity using vertex snapping. This feature works by forcing two objects into positional alignment within the scene by overlapping their vertices at a specific and common point.

For example, consider Figure 1.26. Here, a house object hovers awkwardly above the floor and we naturally want it to align level with the floor and perhaps over to the floor corner. To achieve this, perform the following steps:

  1. Select the house object (click on it or select it from the Hierarchy panel). The object to be selected is the one that should move to align and not the destination (which is the floor), which should remain in place:

    Figure 1.26 – Misaligned objects can be snapped into place with Vertex Snapping

  2. Next, activate the translate tool (W) and hold down the V key for vertex snapping.
  3. With V held down, move the cursor around and see how the gizmo cursor sticks to the nearest vertex of the selected mesh. Unity is asking you to pick a source vertex for the snapping.
  4. Move the cursor to the bottom corner of the house, and then click and drag from that corner to the floor mesh corner. The house will then snap align to the floor, precisely at the vertices.
  5. When aligned this way, release the V key. It should look similar to Figure 1.27:

    Figure 1.27 – Align two meshes by vertices

  6. Now you can assemble a complete scene using the mesh assets included in the Prototyping folder. Drag and drop props in the scene, and using translate, rotate, and scale, you can reposition, realign, and rotate these objects; using vertex snapping, you can align them wherever you need. Give this some practice.

See Figure 1.28 for the scene arrangement that I made using only these tools and assets:

Figure 1.28 – Building a complete level

You'll notice in Figure 1.28 that everything looks relatively flat, with no highlights, shadows, or light or dark areas. This is because scene lighting is not properly configured for best results, even though we already have a light in the scene, which was created initially by default. We'll fix this now.

Adding lighting and a skybox

The basic level has been created in terms of architectural models and layout; this was achieved using only a few mesh assets and some basic tools. Nevertheless, these tools are powerful and offer us a number of options to create a great variety of game worlds. One important ingredient is missing for us, however. This ingredient is lighting.

Let's start setting the scene for the coin collection game by enabling the sky, if it's not already enabled. To do this, perform the following steps:

  1. Click on the Extras drop-down menu from the top toolbar in the scene viewport.
  2. From the context menu, select Skybox to enable skybox viewing. A Skybox is a large cube that surrounds the whole scene. Each interior side has a continuous texture (image) applied to simulate the appearance of a surrounding sky. For this reason, clicking the Skybox option displays a default sky in the scene viewport:

    Figure 1.29 – Enabling the sky

  3. Although the skybox is enabled and the scene looks better than before, it's still not illuminated properly—the objects lack shadows and highlights. To fix this, be sure that lighting is enabled for the scene by toggling on the lighting icon at the top of the scene view, as shown in Figure 1.30. This setting changes the visibility of lighting in the scene view but not in the final game:

Figure 1.30 – Enabling scene lighting in the Scene viewport

Enabling the lighting display for the viewport will result in some differences to the scene appearance and, again, the scene should look better than before. You can confirm that scene lighting is taking effect by selecting Directional Light from the Hierarchy panel and rotating it. All objects in the scene are illuminated based on the rotation of the directional light, so by rotating the light object, you are, in effect, changing the time of day. Moving the object, in contrast, will not affect the scene lighting. A directional light represents a large and very distant light source, existing far beyond the bounds of our game. No matter where you position the lighting object in the scene, the other objects will stay illuminated in the same way. Instead of moving the light object, you can change the Intensity field on the Light component to alter the mood of the scene. This changes how the scene is rendered, as seen in Figure 1.31:

Figure 1.31 – Rotating the scene directional light changes the time of day

Undo any rotations to the directional light by pressing Ctrl + Z on the keyboard. To prepare for final and optimal lighting, all non-movable objects in the scene should be marked as Static. This signifies to Unity that the objects will never move, no matter what happens during gameplay. By marking non-movable objects ahead of time, you can help Unity optimize the way it renders and lights a scene.

To mark objects as static, perform the following steps:

  1. Select all non-movable objects (which includes practically the entire level so far). By holding down the Shift key while selecting objects, you can select multiple objects together, allowing you to adjust their properties as a batch through the Inspector panel.
  2. Enable the Static checkbox via the Inspector panel. The Static checkbox is shown in Figure 1.32:

Figure 1.32 – Enabling the Static option for multiple non-movable objects improves lighting and performance

When you enable the Static checkbox for geometry, Unity autocalculates scene lighting in the background—effects such as shadows, indirect illumination, and more. It generates a batch of data called the GI Cache, featuring light propagation paths, which instructs Unity how light rays should bounce and move around the scene to achieve greater realism.

If your objects are not casting shadows, they may have the Cast Shadows option disabled. To fix this, perform the following steps:

  1. Select all meshes in the scene.
  2. Then, from the Inspector panel, click on the Cast Shadows context menu from the Mesh Renderer component, and choose the On option.

When you do this, all mesh objects should cast shadows, as shown in Figure 1.33:

Figure 1.33 – Enabling cast shadows from the Mesh Renderer component

Voilà! The meshes now cast shadows. Splendid work! In reaching this point, you've created a new project, populated a scene with meshes, and successfully illuminated them with directional lighting. That's excellent. However, it'd be even better if we could explore our environment in the first person. We'll see how to do precisely that next.