I have been exploring the new Sequences package beta for Unity for animation and one of the things it makes heavy use of was Prefab Variants. I had heard of Prefab Variants, but never really quite “got” how they were different from Prefabs. So I did some hunting around and thought I would summarize my findings.
In my hobby project, my goal is to animate characters created using VRoid Studio. When you export a VRM file from VRoid Studio and import it into Unity (using the UniVRM package) you get a prefab created for the character. The prefab is stored in a file on disk (in the Assets hierarchy).
The prefab contains a hierarchy of game objects used to assemble a single character. Here is an example character if you open the prefab. The root object has scripts attached such as “make eyes look at a specified target”, then there are child objects for different aspects of the face, body, hair, and so on. (The exact structure is not important here.)
Dragging the prefab into a scene adds all these objects to the scene.
This is the benefit of a prefab. You can drag the character into many different scenes and get exactly the same set of game objects all correctly initialized. And if the prefab on disk is updated, all scenes are automatically updated as well.
In my case, I extend characters by adding more blendshapes, tweaking some textures (e.g. to make the face be able to blush), adding a backpack, additional scripts to make animation easier, and so forth. Originally I did this by making changes in the scene, testing it, then dragging the game object hierarchy to the assets folder which creates a prefab from the game object hierarchy. (You can turn any tree of objects in a scene into a prefab in this way.)
The problem with making a copy of the original character prefab is if the original prefab gets updated for some reason, the copy does not. In my case, every time I imported an updated VRM file from VRoid Studio, I then had to also update the prefab with my extensions to make sure I picked up all the changes made. (I am leaving out some details here for simplicity – for example, materials for characters are stored in files on disk so are shared between characters by default.)
This is where prefab variants shine. They are prefabs in that they are stored on disk as an asset, but they works a little differently. A prefab variant keeps track of the prefab they are derived from plus changes (overrides) made to the original prefab. There are restrictions on what changes you can made. For example you can override properties, add new game objects, but not reorder children. Here is an example prefab where a bag has been added to the character (a backpack).
In the inspector panel you can look at what a variant has changed. (This is just an example with a single override, adding a bag. Normally I add multiple additional components as well.)
In practice, I may hide the bag then create another variant with the bag visible, creating a variant per set of clothes for the character. It makes it quicker to assemble a new scene.
There were some questions in the forums about the difference between using variants and nesting a prefab inside a prefab. You can do something similar to variants by creating prefabs for all the children (e.g. Face, Body, Hair above) of the main prefab (the character), then creating a prefab per variant of the character by adding the children prefabs to each version of the character. It works, but there are problems with this approach: you have to create more prefabs and manage them all, updating the original prefab imported from VRoid would need child prefabs to be recreated each time, and it does not allow sharing of the root node (which has components and properties on it) – the approach can only be used for children of the root node. Prefab variants solve these problems nicely.
One definition I read for the programmers reading this, prefabs with nested prefabs is “composition”, prefab variants are “inheritance”. Kinda. At the character level. It is rather a deep technical description.
I personally prefer thinking about it at a higher level. I create a character to reuse (reuse = want a prefab), then create a variant for each minor change (e.g. set of clothes they are wearing) for that character (minor changes to override defaults = prefab variant).
Going back to the Unity Sequences beta, what it does is use variants to hold a separate timeline for animations for each variant. E.g. you could have the character dressed in a certain way that is walking. I am not sure I personally like this approach however. I want to line up acting and camera moves across across everything in the scene. Having a separate timeline per character and prop in the scene means I have to open up a timeline per object, jumping around a lot more to line things up. So I am (for now!) planning to not use that capability, adding animation tracks (instead of subsequences) to the higher up timeline object.