© Casey Hardman  2020
C. HardmanGame Programming with Unity and C#https://doi.org/10.1007/978-1-4842-5656-5_5

5. Prefabs

Casey Hardman1 
(1)
West Palm Beach, FL, USA
 

A prefab is a type of asset you’ll store in your project. They act something like a blueprint for objects. You set up a prefab for some kind of object in your game and then add instances of the prefab to your game, in any of your scenes. This connection to the prefab will remain across all the instances, and you can then change the prefab itself to automatically change every instance you’ve placed.

For example, you might make a prefab out of a certain enemy type. You place that kind of enemy throughout your game levels (scenes) possibly hundreds of times. Somewhere down the line, you want to make some change to this enemy type – make it a little bigger or give it a little more health or make it move a little slower. If you had simply copy-pasted your enemy GameObject through all your scenes, you would have to change each one individually and make sure you kept them all consistent. This can be very tedious! But since you made a prefab for the object, you can just change the prefab itself. As an asset in your project, you simply find the prefab in the Project window, edit it, and make the changes you desire. Those changes automatically reflect across all the prefab instances in all your scenes.

Making and Placing Prefabs

To create a prefab out of an existing GameObject in your scene, you can just drag that GameObject from the Hierarchy window into the Project window and drop it into a folder where you want to save the prefab asset. This creates a prefab and automatically associates that GameObject in the scene with that new prefab. In other words, the object you dragged and dropped is no longer some random, one-off object in this scene. It’s now an instance of the prefab.

We’ll create a prefab out of our Skyscraper GameObject we created in the last chapter. Drag the Skyscraper GameObject from the Hierarchy and drop it in the Project. Don’t just drag one of the children, though. It must be the root GameObject, named Skyscraper.

The new prefab asset will be named the same thing: Skyscraper. To place further instances of the prefab – exact copies of our Skyscraper – we can just left-click to drag and drop the prefab asset from the Project window into the Scene window. As you’re dragging the prefab over the Scene, you’ll notice that Unity lets you see where it’s going to be placed, showing the new Skyscraper where your mouse is pointing. It will automatically be placed on the surface of other objects you’re pointing at, whether they be another instance of the Skyscraper or the floor we created earlier. Once you release the left-click, the instance is officially placed in the scene.

Remember what we were learning about pivot points in the previous chapter? If we had left our pivot point in the center of the Cube Base of the Skyscraper, it would not be placed so neatly on the surface of the floor when we set down prefab instances of it. It would stick through the floor. Since the pivot point is the point that will be at the position given to the object, if we want the bottom to be on the surface that we point our mouse at (and we do), we must make that the pivot point. Good thing we did that already! Now when we place the object, it lines up correctly every time.

Editing Prefabs

Place a few extra Skyscrapers onto the floor in the scene, and let’s learn to edit a prefab so we can see all our instances change when we’re done.

To edit a prefab asset, you can double-click the asset in the Project window or click it and then click the “Open Prefab” button just beneath the head of the Inspector.

This opens a sort of fake scene in Unity, where nothing exists but an instance of the prefab. Look at the Hierarchy window, and you’ll see that none of your other GameObjects are there anymore, and a bar stretches across the top of the window showing the prefab name and the little blue box icon that represents a prefab GameObject. This bar has an arrow on its left side that can be clicked to bring you out of prefab editing and back to the scene you were in before.

There’s also a similar bar stretching across the top of the Scene window, which lists, from left to right, the scene environments you’ve been in. The one you’re in now will be on the rightmost side, and the path you’ve traveled to get there will be on its left side, as shown in Figure 5-1.
../images/486227_1_En_5_Chapter/486227_1_En_5_Fig1_HTML.jpg
Figure 5-1

The top of the Scene view while editing our Skyscraper prefab

As of right now, it looks simple: Scenes on the left, which is the normal view where you’re looking at the loaded scene itself, and then the Skyscraper prefab, which is where we are now, viewing just the objects that are part of the prefab. This bar becomes more notably useful when you begin having prefabs within prefabs (it sounds scary, I know) and you start opening a prefab while viewing another prefab. The bar pretty much shows you the rabbit hole you’ve gone down, in proper order. At any point, you can click one of the names to switch back to that environment.

Let’s change our Skyscraper here in the editing environment. The Scene window will function as it normally does, so all our transform tools will work as they did before. Do something crazy to the Skyscraper, like grab the Cube Middle and drag it high above the Cube Base. Then, press Ctrl+S, or click the Save button all the way on the right side of the bar at the top of the Scene view. This makes the changes take effect. If your prefab has been changed and you try to navigate out of the editing environment without saving, Unity will stop you and ask if you’re sure you want to discard the changes. If you’d rather just automatically save all your changes, you can check the “Auto Save” box just to the right side of the Save button we just clicked.

Once you’ve made your change and saved the prefab, navigate out of the prefab editing environment using the top bar of the Hierarchy window (click the arrow on the left side) or the Scene window (click “Scenes” on the left side).

Now that you can see your scene again, all the Skyscrapers will have changed to reflect the prefab.

Another way to edit prefabs is to simply make some changes on an instance of the prefab in your scene. Then, to apply those changes to the prefab, just drag and drop the instance from the Hierarchy to the asset in the Project window. This makes the asset the same as your modified instance in one simple motion. For example, we could have made our change to one of the Skyscrapers in the scene we were working on and then dragged and dropped that modified Skyscraper from the Hierarchy to the asset in the Project, and all of the other instances in the scene would have updated to match it. Try it yourself, if you want. There’s no limit to how often you can change your prefabs!

Overriding Values

Sometimes, you want a prefab instance that behaves a little differently than the blueprint dictates – such as an enemy with more speed or an enemy that holds an axe instead of a hammer.

You can make little changes like this to an instance of a prefab, and Unity will keep track of what is different across your instances. These are called overrides. To describe it technically, when you override something on a prefab instance, any change to that something on the prefab asset will not reflect on the overridden instance.

For example, let’s say we have a prefab “Soldier” representing some enemy soldier that we’ve placed many instances of across all of our scenes. But we want to put down an instance that has a bit more health than the rest, a particularly strong soldier. We go into the Inspector and increase the health of this soldier instance, and we rename it to Burly Soldier so we know it’s special.

But later, we decide that all of our soldiers have too much health, and we want to decrease it a little. To do this, we change the prefab asset, decreasing its health a little. This causes every instance of the prefab to reflect those changes, making them have a little less health and saving us a lot of trouble finding them all and changing the health of each one individually.

However, since we overrode the health for our Burly Soldier, his health won’t change. Unity will recognize that we overrode that value and leave it alone when we change the prefab asset.

This way, overrides are preserved when the prefab asset is changed, so that any one-off differences you make are not undone the next time you edit and save your prefab.

This applies to values in the components of the GameObjects associated with the prefab – including nested (child) GameObjects. This applies as well to the Transform component, so that position, rotation, and scale can be overridden for children of the prefab root (the master parent of the prefab). The root GameObject itself does not concern itself with the position and rotation of the parent, however (it would cause some pretty strange anomalies if it did). You can consider the position and rotation of the root GameObject to always be overridden – even if it is the same as that of the prefab itself, it will not be updated if you edit the prefab to rotate or position it differently. However, since the children use local position and rotation based off the root, their position and scale won’t be considered “overridden by default.” We’ll go over this with an example in a bit.

But component values aren’t the only things that can count as overrides. Removing components, adding components, and adding extra child GameObjects all count as overrides as well. So if you delete a component from some GameObject in your prefab instance and then later update the prefab asset, the deleted component will not be added back to the instance. Unity recognizes that you made a conscious override and preserves it. The same goes for adding an extra component: it won’t be removed when you edit the prefab.

Component values that have been overridden will have bold (thicker) text for their name and value. The Transform of your base GameObject will have a bold position and rotation, because this is world position and isn’t associated with the prefab. But the local position of children will only be bold if you have changed it from the prefab setting.

Let’s override one of the Skyscraper instances we have in our scene. Using the position tool (hotkey W), just grab the Cube Middle of one of the Skyscrapers and pull it up or down a good bit, so it’s noticeably off from the rest of the instances. You’ll notice that its Y position in the Inspector will become bold, because it’s now an overridden local position. It’s not in the same place as it should be according to the prefab, so it is marked as an override.

Now that one of the instances is unique, let’s edit the prefab and drag the Cube Middle back down to the position it was before (or near to it), touching the Cube Base as it should be. It’s okay if it’s not exact. Save the prefab and then return to the scene.

All but one Skyscraper should reflect the changes now. Since we overrode the local Y position of the Cube Middle for one of the instances, when that value is changed in the prefab, it is ignored by this one instance. We have given it a special value, and Unity will respect that and preserve it for us.

As I said before, this applies to local positions and rotations – the children of the prefab root. The root is the GameObject holding all the others, which, for this prefab, is the empty GameObject we named Skyscraper. The root GameObject is not concerned with position and rotation of the prefab. You’ll notice that even if you give a prefab instance the exact same position and rotation as the prefab asset (by comparing their Transform components in the Inspector), the position and rotation of the instance is still bold. It’s overridden by default. If you edit the prefab and rotate the root or move the root a few units in one direction, that change isn’t going to take effect to any of the instances. This is just as well – you wouldn’t really expect it to. As far as we’re concerned, changes to the position and rotation of the root GameObject shouldn’t affect the instances. However, the rotation of the root will be used when placing new instances in the Scene by dragging and dropping, which can be a useful setting to specify at times.

There’s an easy way to view the overrides you have applied to a prefab instance. Select the Skyscraper instance that you have overridden the Y value for. As long as you have the root selected (the one named Skyscraper, not any of the children), you’ll see some extra options in the header of the Inspector (just under the field containing the name of the GameObject). The text “Prefab” will be on the left, and to its right side, you’ll have buttons “Open” and “Select,” as shown in Figure 5-2.
../images/486227_1_En_5_Chapter/486227_1_En_5_Fig2_HTML.jpg
Figure 5-2

Prefab options are listed for the Skyscraper GameObject

“Open” will open the associated prefab asset for editing, and “Select” will select the prefab asset in the Project window (in large projects, this can be easier than fishing around for it yourself). To the right side of these buttons is a dropdown button titled “Overrides.” Clicking this button will show a hierarchy of GameObjects included in the prefab. Nested inside GameObjects, it will also show their components which have had values overridden, as well as components which have been added or removed and GameObjects which have been added.

The purpose of this list is essentially to show you all of the differences between a prefab instance and the actual prefab asset and to allow you to revert those changes, which means switch back to how it is on the asset, or apply them, which means make the change on the asset as well, so that it’s no longer an override – it’s just the norm. There are also the buttons “Revert All” and “Apply All” on the bottom of the list, which, as their titles suggest, revert or apply all the overrides to the prefab asset at once.

For the overrides of our Skyscraper, we should see the hierarchy showing Skyscraper, inside that (indented to the right) Cube Base, and then Cube Middle inside that; and then, inside Cube Middle, we’ll see its Transform component. Clicking the individual GameObject names will show a popup window on the left saying “No Overrides.” But clicking the Transform will cause the popup window to display two views of the Transform values side by side, as shown in Figure 5-3.
../images/486227_1_En_5_Chapter/486227_1_En_5_Fig3_HTML.jpg
Figure 5-3

The Overrides dropdown list, with the Transform component of Cube Middle selected. This results in the popup boxes stretching out on the left side

The left side is titled “Prefab Source” and is all grayed out so we can’t edit the values. It is just showing us what the values are set to on the prefab asset and does not let us make changes. The right side is titled “Override” and shows the values of the Transform component, allowing us to edit them right there if we desire. At the top-right corner of this “Override” pane, we see the buttons to revert and apply the overridden values. This is how you revert/apply for a specific component. Let’s revert the change to make this Skyscraper go back to normal and stop defying the laws of physics. Just click the “Revert” button.

One final note on overrides: You can’t remove a GameObject from a prefab as an override. You can add them, but you can’t remove them. This is because you can’t just restructure a prefab instance like this – you must unpack it first, which disassociates it with the prefab altogether so that it’s just a bunch of normal GameObjects. This is done by an option available when right-clicking the GameObject. Or you can edit the prefab asset and delete the GameObjects, but of course, this applies to all instances. But neither of these is a satisfactory solution. Instead, to effectively remove a GameObject for a single instance, you can disable it with the checkbox on the left side of the name field in the Inspector header, which is essentially keeping the object around, but not running any of the functionality of its components: it won’t be rendered, and it won’t collide with things. This also disables all its children.

This is how you might do something like having a single instance of an enemy wield an axe instead of a hammer, as we mentioned at the start of this chapter. Disable the hammer GameObject that comes with the prefab by default, and then you can add a new axe GameObject as an override and position it where the hammer would normally be.

Nested Prefabs

One neat feature that we didn’t use to have in Unity is the concept of nested prefabs. We can have prefab instances which are part of the hierarchy of other prefabs. Changes made to a nested prefab through its asset will automatically apply to instances of the prefab even if they are nested inside other prefabs.

For example, you might have a bunch of prefabs for different types of enemies – soldiers with male and female versions, ones with thick armor and ones with light armor, or ones which use different kinds of skills or magic. You have a variety of different weapons they’ll wield – some use swords and others use spears or axes. Many of them will end up using the same weapon. So you make prefabs for the weapons and nest an instance of the weapon prefab inside each of the enemy prefabs.

This way, each enemy prefab has an instance of the weapon prefab inside it. If you ever want to change something about the weapon, you can change that weapon prefab, and all the enemies who use that weapon type will reflect the changes. If you had not used prefabs for the weapons, you’d just have separate instances of the weapon in each of the enemy prefabs, probably copy-pasting them from one to the other. Then if you wanted to make a change to a weapon, you’d have to go through each prefab that uses that weapon and change it individually.

You’ve probably noticed that, in the Hierarchy window, the icon to the left of the name of a GameObject is sometimes a blue cube and other times a gray cube. Perhaps you’ve figured it out already, but a blue cube means that a GameObject is the root of a prefab. A gray cube means it is not the root.

The color of the name also differs. Some have black text for their name and others blue. Blue text is for the GameObjects which are part of the prefab. Black text is for those which are not – they may be added as an override, but they’ll still have black text because they aren’t included in the prefab asset itself.

When you nest prefabs, you’ll see blue cube icons as children of other blue cube icons. This helps you distinguish which pieces of a GameObject hierarchy are part of another prefab.

Aside from this, nested prefabs are pretty self-explanatory – prefabs within prefabs. But one notable difference is the applying of overrides made to nested prefabs.

The Overrides dropdown button in the Inspector will only show for the root of the prefab – not for nested prefabs. With an override applied to a nested prefab, you’ll be offered two options when using the Overrides list to apply changes made to the prefab: one to apply the change as an override to the root prefab and another to apply the change to the nested prefab itself. The difference here is whether or not the nested prefab asset has the change applied to it. Either way, the change is going to affect the root prefab, since it contains an instance of the nested asset – the question is, do you want the nested prefab, and all instances of it (nested or not) to have the change? Or do you just want the change to exist in the root prefab’s instance of the nested prefab, as an override? This just depends on the situation, but it’s an important distinction to make.

These two options will show whenever you click the Apply button when selecting an override to a nested prefab in the Overrides dropdown. Where before the Apply button would offer a dropdown list with only one option, it will now offer two: one to apply to the nested prefab itself and the other to apply as an override to the root prefab.

Prefab Variants

A prefab variant is a prefab asset that overrides another prefab called the base. It’s like a copy which serves as a way to make a variation of an existing prefab. Values that haven’t been overridden in the variant will be kept up to date with their settings in the prefab base.

For example, you might have variations of enemy types: a larger version of the same enemy that has more health but moves slower or a version that wields a different sort of weapon. All the base functionality is kept in the base prefab – the model, the animations, and the scripts that provide it with its AI and logic. But little customizations are made on the component values, or a weapon is disabled and a different one is swapped into its place.

This is a useful way to keep prefabs working for you while still providing you some flexibility. You can have these variations with their overrides while still benefitting from the fact that any change to the base prefab will automatically take effect on the variants, unless the variant has overridden the value. If you had instead copy-pasted the base prefab to make the variants, any change that you wish to make to some common value across the prefab and all of the variants would have to be done individually for each variant, which is the main problem that prefabs seek to solve.

To create a prefab variant, right-click a prefab asset in the Project window, select Create, and then select Prefab Variant, an option which can only be clicked if you have right-clicked a prefab. This will create a new variant next to the base prefab in the Project and will allow you to type out a name for it. Alternatively, you can create a new variant by dragging a prefab instance from the Hierarchy to the Project, which will result in a prompt asking if you’d like to create a new, original Prefab or a variant of the existing prefab.

You can even create variants whose base is another variant, if you wish.

The icon for prefab variants in the Project and Hierarchy is a blue cube, like prefabs, but it is decorated with a couple arrows to indicate that it is a variant. When you select a prefab variant, the Inspector will point at the base prefab in the header, just beneath the name of the variant.

When using variants, it’s important to note that they pretty much work like a prefab instance with overrides. Anything that is different on the variant is considered an override to the base. As such, you often don’t want to apply any of their overrides, because their overrides apply to the base prefab, not the variant asset. The variant asset is simply a place to store your overridden version of the prefab. You’ll override what you want – change values, add components, remove components, add GameObjects, or deactivate GameObjects, whatever you need – and save the variant asset. That’s all. Applying overrides is not necessary.

For example, if you were to create a “Bulky” variant of your enemy type, edit it, increase its scale, and decrease its speed and then go to the Overrides dropdown and apply all of the changes, you would end up switching the base prefab to be Bulky, and the variant would be the same as the base – which eliminates the purpose of having the variant at all. To make this distinction clear, the Apply All button in the Overrides dropdown will instead read “Apply All to Base” when working with a variant, just to give some extra warning.

Summary

In this chapter, we learned the following:
  • A prefab is a GameObject that is saved as an asset by dragging it from the Hierarchy window and dropping it in the Project window.

  • We place instances of the prefab asset by dragging the asset from the Project window into the Hierarchy or into the Scene.

  • The prefab asset can be edited by double-clicking it in the Project window. Any changes made here will automatically occur on all instances of that prefab across all of your scenes.

  • If you’re creating a certain type of GameObject that you plan on copying and placing many instances of throughout your scenes (like an enemy or powerup), you should make a prefab for it and place instances of the prefab. You’ll only have to edit the prefab once, and all of the instances will update. This can save you a lot of trouble.

  • Any changes made to the values of components in a prefab instance are qualified as overrides. If the prefab asset makes a change to a field that the instance has overridden, the change will not occur on the instance. In other words, overridden values are preserved, allowing us to make one-off changes to specific instances that won’t be undone the next time we edit the asset.

  • A prefab variant is a prefab asset that copies from another prefab asset. A variant can be used to create a consistent different version of an existing prefab asset, such as an enemy with a different kind of weapon or with more health. Values which are not overridden are in control of the base prefab asset. Those which are overridden are in control of the variant asset.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.223.106.232