In the previous chapter, we created the prototype of our level. Now, let’s suppose that we have coded the game and tested it, confirming the game idea is fun. With that, it’s time to replace the prototype art with the real finished art. We are going to actually code the game in the next chapter, Chapter 5, Introduction to C# and Visual Scripting, but for learning purposes, let’s just skip that part for now. In order to use the final assets, we need to learn how to get them (images, 3D models, and so on), how to import them into Unity, and how to integrate them into our scene.
In this chapter, we will examine the following topics:
Let’s start by learning how to get assets in Unity, such as 3D models and textures.
We have different sources of assets we can use in our project. We can simply receive a file from our artist, download them from different free and paid assets sites, or we can use the Asset Store, Unity’s official asset virtual store, where we can get free and paid assets ready to use with Unity. We will use a mix of downloading assets from the internet and from the Asset Store, just to use all possible resources.
In this section, we will cover the following concepts related to importing assets:
In terms of getting art assets for our project, let’s start with our terrain textures. Remember that we have our terrain painted with a grid pattern, so the idea is to replace that with grass, mud, rock, and other kinds of textures. To do that, we need images. In this case, these kinds of images are usually top-down views of different terrain patterns, and they have the requirement of being “tileable,” meaning you can repeat them with no noticeable pattern in their connections. You can see an example of this in the following image:
Figure 4.1: Left – grass patch; Right – the same grass patch separated to highlight the texture tiling
The grass on the left seems to be one single big image, but if you pay attention, you should be able to see some patterns repeating themselves. In this case, this grass is just a single image repeated four times in a grid, like the one on the right. This way, you can cover large areas by repeating a single small image, saving lots of RAM on the user’s computer.
The idea is to get these kinds of images to paint our terrain. You can get them from several places, but the easiest way is to use Google Images or any image search engine. Always check for copyright permissions before using something from these sources. To do this, follow these steps:
PATTERN tileable texture
, replacing PATTERN
with the kind of terrain you are looking for, such as grass tileable texture
or mud tileable texture
. In this case, I am going to type grass tileable texture
and then press Enter to search.Figure 4.2: Google search for images
Try to check the image’s resolution before picking it. Try to select squared images that have a resolution less than 1024 x 1024 for now.
Figure 4.3 Save image as… option
Now that you have downloaded the image, you can add it to your project in several ways. The simplest one would be by doing the following:
Textures
folder in the Project window in Unity.Textures
folder in the Unity Project Window:Figure 4.4: Texture being dragged from Windows File Explorer to Unity’s Project view
For simple textures like these ones, any search engine can be helpful, but if you want to replace the player’s base geometry with detailed walls and doors or place enemies in your scene, you need to get 3D models. If you search for those in any search engine using keywords such as “free zombie 3D model,” you will find endless free and paid 3D models sites such as TurboSquid and Mixamo, but those sites can be problematic because those meshes are usually not prepared for being used in Unity, or even games. You will find models with very high polygon counts, incorrect sizes or orientations, unoptimized textures, and so on. To prevent those problems, we’ll want to use a better source, and in this case, we will use Unity’s Asset Store, so let’s explore it.
The Asset Store is Unity’s official asset marketplace where you can find lots of models, textures, sounds, and even entire Unity plugins to extend the capabilities of the engine. In this case, we will limit ourselves to downloading 3D models to replace the player’s base prototype. You will want to get 3D models with a modular design, meaning that you will get several pieces, such as walls, floors, corners, and so on. You can connect them to create any kind of scenario.
In order to do that, you must follow these steps:
Figure 4.5: Asset Store moved message
Figure 4.6: 3D assets menu
Figure 4.7: 3D assets menu
As you can see, there are several categories for finding different types of assets, and you can pick another one if you want to. In Environments, you will find 3D models that can be used to generate the scenery for your game.
Figure 4.8: Free Assets option
Figure 4.9: Preview of Asset Store searched packages
Figure 4.10: Asset Store package details
Figure 4.12: Package Manager showing assets
Figure 4.13: Assets to import selection
Take into account that importing lots of full packages will increase your project’s size considerably, and that, later, you will probably want to remove the assets that you didn’t use. Also, if you import assets that generate errors that prevent you from playing the scene, just delete all the .cs
files that come with the package. They are usually in folders called Scripts
. Those are code files that might not be compatible with your Unity version:
Figure 4.14: Code error warning when hitting play
Before you continue with this chapter, try to download a character 3D model using the Asset Store, following the previous steps. In order to do this, you must complete the same steps as we did with the level environment pack but look in the 3D | Characters | Humanoid category of the Asset Store. In my case, I picked the Robot Hero: PBR HP Polyart package:
Figure 4.15: Character package used in our game
Now, let’s explore yet another source of Unity Assets: Unity Packages.
The Asset Store is not the only source of asset packages; you can get .unitypackage files from the internet, or maybe from a coworker who wants to share assets with you.
In order to import a .unitypackage
file, you need to do the following:
Figure 4.16: Importing custom packages
.unitypackage
file in the displayed dialog.Now that we have imported lots of art assets, let’s learn how to use them in our scene.
We have just imported lots of files that can be used in several ways, so the idea of this section is to see how Unity integrates those assets with the GameObjects and components that need them.
In this section, we will cover the following concepts related to importing assets:
Let’s start by using the tileable textures to cover the terrain.
In order to apply textures to our terrain, do the following:
Figure 4.17: Terrain Paint Texture option
Figure 4.18: Texture to paint picker
Each time you add a texture to the terrain, you will see that a new asset called New Layer N is created in the Project view. It holds data of the terrain layer you have created, and you can use that one on other terrains if you need to. You can also rename that asset to give it a meaningful name. Also, you can reorganize those assets in their own folder for organization purposes.
Figure 4.19: Painting texture options
Figure 4.20: Results of painting our terrain with three different textures
Of course, we can improve this a lot using lots of the advanced tools of the system, but let’s just keep things simple for now. Now, let’s see how we can integrate the 3D models into our game.
If you select one of the 3D assets we have downloaded previously and click the arrow to its right, one or more sub-assets will appear in the Project window. This means that the 3D model files we downloaded from the Asset Store (the FBX files) are containers of assets that define the 3D model:
Figure 4.21: Mesh picker
Some of those sub-assets are meshes, which are a collection of triangles that define the geometry of your model. You can find at least one of these mesh sub-assets inside the file, but you can also find several, and that can happen if your model is composed of lots of pieces. For example, a car can be a single rigid mesh, but that won’t allow you to rotate its wheels or open its doors; it will be just a static car, and that can be enough if the car is just a prop in the scene, but if the player will be able to control it, you will probably need to modify it. The idea is that all pieces of your car are different GameObjects parented to one another in such a way that if you move one, all of them will move, but you can still rotate its pieces independently.
When you drag the 3D model file to the scene (not the sub-asset), Unity will automatically create all the objects for each piece and its proper parenting based on how the artist created those. You can select the object in the Hierarchy and explore all its children to see this:
Figure 4.22: Sub-object selection
Also, you will find that each of those objects may have its own Mesh Filter
and Mesh Renderer
components, each one rendering just that piece of the model. Remember that the Mesh Filter
is a component that has a reference to the mesh asset to render, so the Mesh Filter
is the one using those mesh sub-assets we talked about previously. In the case of animated characters, you will find the Skinned Mesh Renderer
component instead, but we will discuss that component later, in Part 3, Improving Graphics.
Now, when you drag the 3D model file into the scene, you will get a similar result as if the model were a Prefab and you were instancing it. But 3D model files are more limited than Prefabs because you can’t apply changes to the model. If you’ve dragged the object onto the scene and edited it to have the behavior you want, I suggest that you create a Prefab to get all the benefits we discussed in Chapter 2, Editing Scenes and GameObjects, such as applying changes to all the instances of the Prefab and so on. Never create lots of instances of a model from its model file—always create them from the Prefab you created based on that file to allow you to add extra behavior to it.
That’s the basic usage of 3D meshes. Now, let’s explore the texture integration process, which will give our 3D models more detail.
Maybe your model already has the texture applied but has a magenta color applied to all of it. If this is the case, that means the asset wasn’t prepared to work with the Universal Render Pipeline (URP) template you selected when creating the project.
Some assets in the Asset Store are created by third-party editors and could be meant to be used in older versions of Unity:
Figure 4.23: Mesh being rendered with erroneous or no material at all
One option to fix magenta assets is using the Render Pipeline Converter, a tool that will find them and reconfigure them (if possible) to work with URP. To do so, perform the following steps every time you import an asset that looks magenta:
Figure 4.24: Upgrading older assets to URP
Figure 4.25: Fixing Material to work with URP
You will need to close the window for it to detect new magenta assets that weren’t there before opening it. The con of this method is that, sometimes, it won’t upgrade the material properly. Luckily, we can fix this by reapplying the textures of the objects manually. Even if your assets work just fine, I suggest that you reapply your textures anyway, just to learn more about the concept of materials.
A texture is not applied directly to the object. That’s because the texture is just one single configuration of all the ones that control the aspect of your model. In order to change the appearance of a model, you must create a Material. A material is a separate asset that contains lots of settings about how Unity should render your object. You can apply that asset to several objects that share the same graphics settings, and if you change the settings of the material, it will affect all the objects that are using it. It works like a graphics profile.
In order to create a material to apply the textures of your object, you need to follow these steps:
Car
, Ship
, Character
, and so on).Dragging the material will change the material’s property of the MeshRenderer
component of the object you have dragged.
Figure 4.26: Base Map property of URP materials
With this, you have successfully applied the texture to the object through a material. For each object that uses the same texture, just drag the same material. Now that we have a basic understanding of how to apply the model textures, let’s learn how to properly configure the import settings before spreading models all over the scene.
As we mentioned earlier, artists are used to creating art assets outside Unity, and that can cause differences between how the asset is seen from that tool and how Unity will import it. As an example, 3D Studio Max can work in centimeters, inches, and so on, while Unity works in meters. We have just downloaded and used lots of assets, but we have skipped the configuration step to solve those discrepancies, so let’s take a look at this now.
In this section, we will cover the following concepts related to importing assets:
Let’s start by discussing how to configure 3D meshes.
In order to change the model’s import settings, you need to locate the model file you have downloaded. There are several file extensions that contain 3D models, with the most common one being the .fbx
file, but you can encounter others such as .obj
,.3ds
, .blender
, .mb
, and so on. You can identify whether the file is a 3D mesh via its extension:
Figure 4.27: Selected asset path extension
Also, you can click the asset and check in the Inspector for the tabs you can see in the following screenshot:
Figure 4.28: Mesh materials settings
Now that you have located the 3D mesh files, you can configure them properly. Right now, the only thing we should take into account is the proper scale of the model. Artists are used to working with different software with different setups; maybe one artist created the model using meters as its metric unit, while other artists used inches, feet, and so on. When importing assets that have been created in different units, they will probably be unproportioned, which means we will get results such as humans being bigger than buildings and so on.
The best solution is to just ask the artist to fix that. If all the assets were authored in your company, or if you used an external asset, you could ask the artist to fix it to the way your company works, but right now, you are probably a single developer learning Unity by yourself. Luckily, Unity has a setting that allows you to rescale the original asset before using it in Unity. In order to change the “Scale Factor” of an object, you must do the following:
Figure 4.29: Using a capsule as reference for scale
Figure 4.30: Model mesh options
There are plenty of other options to configure, but let’s stop here for now. Now, let’s discuss how to properly configure the textures of our models.
Again, there are several settings to configure here, but let’s focus on the Texture Size for now. The idea is to use the size that best fits the usage of that texture, and that depends on lots of factors.
The first factor to take into account is the distance from which the object will be seen. If you are creating a first-person game, you will probably see lots of objects near enough to justify a big texture, but maybe you have lots of distant objects, such as billboards at the top of buildings, which you will never be near enough to see the details of, so you can use smaller textures for that.
Another thing to take into account is the importance of the object. If you are creating a racing game, you will probably have lots of 3D models that will be on screen for a few seconds and the player will never focus on them; they will be paying attention to the road and other cars. In this case, an object such as a trash can on the street can have a little texture and a low polygon model and the user will never notice that (unless they stop to appreciate the scenery, but that’s acceptable).
Finally, you can have a game with a top-down view that will never zoom-in on the scene, so the same object that has a big texture in first-person games will have a less detailed texture here. In the following images, you can see that the smaller ship could use a smaller texture:
Figure 4.31: The same model seen at different distances
The ideal size of the texture is relative. The usual way to find it is by changing its size until you find the smallest possible size with a decent quality when the object is seen from the nearest position possible in the game. This is a trial-and-error method. In order to do that, you can do the following:
.png
, .jpg
, or .tif
extensions.Now that you have imported, integrated, and configured your objects, let’s create our player’s base with those assets.
Let’s start replacing our prototype base using the environment pack we have downloaded. To do that, you must do the following:
corner
keyword:Figure 4.32: Mesh picker
Figure 4.33: Positioning the mesh on a placeholder for replacement
wall
keyword in the Project Window.You can select an object and press the V key to select a vertex of the selected object. Then you can drag it, click on the rectangle in the middle of the translate gizmo, and direct it to a vertex of another object. This is called Vertex Snapping. It allows you to connect two pieces of the scene exactly as intended.
Figure 4.34: Connecting two modules
Figure 4.35: Chain of connected modules
You can move an object while pressing the Ctrl key (Command on Mac) to snap the object’s position so that the clones of the wall can be easily located right next to the others. Another option is to manually set the Position
property of the Transform
component in the Inspector.
Figure 4.36: Floor modules with a hole for the pit
Base
. Remember to create an empty object and drag the base pieces into it:Figure 4.37: Mesh sub-assets
After a lot of practice doing this, you will slowly gain experience with the common pitfalls and good practices of modular scene design. All the packages have a different modular design in mind, so you will need to adapt to them.
In this chapter, we learned how to import models and textures and integrate them into our scene. We discussed how to apply textures to the terrain, how to replace our prototype mesh with modular models, how to apply textures to those, and how to properly configure the assets, all while taking several criteria into account according to the usage of the object.
With this, we have finished Part 1 of this book and discussed several basic Unity concepts we will use throughout the book. In Part 2, we will start coding the gameplay of our game, like the player’s movement and the health system. We will start learning how to create our own components to add behavior to our objects and the basic anatomy of a script.