Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

prefab variant vs nested prefab

Discussion in 'Prefabs' started by laurentlavigne, Oct 25, 2018.

  1. laurentlavigne

    laurentlavigne

    Joined:
    Aug 16, 2012
    Posts:
    6,225
    If I nest a prefab within another prefab and make NP1 then nest NP1 under a root NP2 then override a few things in NP2, if I change NP1 then NP2 will change.
    So what is the difference with a prefab variant and when to use which?
     
  2. 5argon

    5argon

    Joined:
    Jun 10, 2013
    Posts:
    1,555
    You can think of it as a way to store specific override setups for later use. You could have a variant with different kind of overrides in NP2 or different overrides in the inner NP1.

    If I have a flower with 6 petals then I could make a variant with 4 petals. Both are stored as an asset and I can instantiate them. Changing things on the 6 petals version would update the 4 petals variant to asides from the petal count.

    I have a health, MP, stamina bar which are all variant of a generic grey colored bar but with different color + different nested text prefab. I made them a variant rather than override of the generic bar because I use them in multiple places. Also when I decided to make the MP bar glow when full but not other kind of bars I can do it only on my MP variant.
     
  3. laurentlavigne

    laurentlavigne

    Joined:
    Aug 16, 2012
    Posts:
    6,225
    I get that, how is it different from a prefab nested inside another with overrides?
     
  4. laurentlavigne

    laurentlavigne

    Joined:
    Aug 16, 2012
    Posts:
    6,225
  5. 5argon

    5argon

    Joined:
    Jun 10, 2013
    Posts:
    1,555
    If you do nested, the overrides you made is serialized with the scene, it has no "root" of that specific override, it has only the original root with non-overriden values. If you then duplicate that 10 times and later decided you want all of them change to some other kind of override then it is a lot of work. (The duplicated GO are instances of an overridden prefab, which has no connection to each other regarding to the overridden value)

    A variant is different, it is stored in the project. If you made your override into a variant first before duplicating, then they all have the same new root in the project now. (They are now instances of a variant) It is easy to change something at the variant file stored in your project.


    Yeah I felt the same way.. I think what I learned by actually using the variant is completely different from that definition (It should actually converges to the same definition but I am going by my understanding)
     
    laurentlavigne likes this.
  6. SteenLund

    SteenLund

    Unity Technologies

    Joined:
    Jan 20, 2011
    Posts:
    639
    not a prank

     
    laurentlavigne likes this.
  7. Flavelius

    Flavelius

    Joined:
    Jul 8, 2012
    Posts:
    943
    But as far as i know a prefab is also stored in the project, so if i make a new prefab out of the scene overrides i have a 'variant'?
    This would only apply if i drag the overridden one into a new empty (nest it), i guess, so in my understanding it's also just that; the only difference is the root. Or am i misunderstanding something?
     
    laurentlavigne likes this.
  8. laurentlavigne

    laurentlavigne

    Joined:
    Aug 16, 2012
    Posts:
    6,225
    Thanks it's a fantastic video and I didn't know the technical aspect of it, good to see that every prefab is now a scene, this was suggested years ago and was a high point on a lot of devs wishlists.
    So a variant is a scene with only one prefab, the original, with overrides. Why was this needed though? Wouldn't a new root with that prefab and its override do the trick? Were there scenarios during development that warranted this?

    Ok... can you explain your workflow?
     
  9. 5argon

    5argon

    Joined:
    Jun 10, 2013
    Posts:
    1,555
    Prefab is stored in the project, prefab variant is stored in the project, but prefab with overrides is not stored in the project. Variant is a way to serialize those overrides in a way while still retaining relationship to one another master prefab.

    In my game prefab variant is very crucial. I am making a music game. Each song has a song jacket. Those jacket will be always put in a decoration picture frame. That frame has a MonoBehaviour script which it can change its frame border, change color, apply an image saying "New", etc. Also, each song is in a folder that will be put in a bundle by the Addressable Asset System, so songs can be added to the game via runtime download later.

    In my project, I have that frame as a prefab named "MasterJacket"

    For each song, I made a variant from "MasterJacket" named "SongNameJacket" then put it in the song's folder ready to be bundled. (MasterJacket stays in the main game) Then using prefab edit mode on the variant, I replace the blank image with a specific song jacket.

    At runtime, I can instantiate the variant SongNameJacket and have it immediately showing that song's jacket. Previously before the new prefab workflow I would instantiate MasterJacket and then use scripting to replace the Image.sprite component. This is no longer needed, just instantiate the variant.

    I also can make a specific song jacket flashing by default by nesting a Flash prefab inside the variant. Previously, I would make a public method Flash on the script in MasterJacket and call it when a song name match the database which says which song should flash. Now those song-specific information is embeded in the variant. Just instantiate the variant.

    Later I decided to change the frame for all songs, I can make change to just the MasterJacket and all variant I made would receive the change. Without variant I would not be able to do this.
     
  10. Flavelius

    Flavelius

    Joined:
    Jul 8, 2012
    Posts:
    943
    I'm still not sure if i just misunderstand something, but i am able to store a prefab with overrides in the project while maintaining a relationship to a master prefab by nesting it the way it was described earlier. I attached a sample project (the override is in the collider size)
     

    Attached Files:

  11. 5argon

    5argon

    Joined:
    Jun 10, 2013
    Posts:
    1,555
    Ah.. my bad. "In the project" I meant literally in the "Project" panel as a separated asset file. The prefab override you stored is a part of Scene object file (which is technically also "stored in the project"). But I meant, the variant is able to be on its own like a normal prefab without relationship to any scene. (Rather, the scene reference them)
     
  12. Flavelius

    Flavelius

    Joined:
    Jul 8, 2012
    Posts:
    943
    If you open the example project you can see that it's stored as an asset file without relationship to any scene, i just put it into a scene when i created it, that's why it's still in there.
     
  13. 5argon

    5argon

    Joined:
    Jun 10, 2013
    Posts:
    1,555
    Ok I finally get it now.

    Yes if you nest a collider with longer box overridden one level as a pseudo variant, then you don't need the variant feature. But conceptually, can you call your PseudoVariant game object "the Original with longer collider"? I think no, because the actual thing is nested one level deep. The shape is different. You might feel that "only differing at root" definition might sounds too trivial to be a new named feature, but it helps a lot in design if you use "the definition of variant" in your code because in Unity the root object means a lot. (For example, between having to search or not at all, etc.)

    If I have a code which has an intention of spawning "a thing (game object) with box collider". Then going by this definition, it should working perfectly whether I choose to give it your Original object or "any variant" of it. I am now using the definition of a variant in my code design. (But there is no actual check if it is really a variant or not. Just a concept.)

    Then, if I use your PseudoVariant with this code it won't work, since I have programmed it to instantiate and `GetComponent<BoxCollider>` on the instantiated object which it will not find the component on the pseudo variant, it is one level deeper. To make this concept work, the prefab variant feature is needed.

    Another story,

    Just now I used the variant feature in a way where it was not possible before again, I have a uGUI `Image` which will stretch to any parent it spawn in using Aspect Ratio Fitter : Fit In Parent component it has at the root. The real aspect of this image is 16:9, on an iPad it would create a letterbox at top and bottom. On iPhone XS it would create a letterbox at left and right side.

    But I have one scene where it looks ugly to have a letterbox on any aspect ratio, so I decided I want an another version with enlarged image and cropped area instead.

    In that scene I would instead spawn a variant of this Image. On that variant, the Aspect Ratio Fitter was modified to use the Width Control Height mode instead. Aspect Ratio Fitter works by looking at the immediate parent of this object, so pseudo variant nesting will not work seamlessly since it will find just the dummy nest object not the real parent it should shape-shift to.

    And previously just a game object it is not possible to store an override of top level Transform/RectTransform. Now I could store a custom anchor and pivot point different from the master prefab so that the cropping goes in a way that it does not cut out important part of the image in any aspect ratio.

    uGUI relies heavily on parent-child mechanism, being able to vary the root could be used to save a lot of time.

    This is correct. But it is unexpectedly useful.
     
    Last edited: Oct 29, 2018
    laurentlavigne and Flavelius like this.
  14. Flavelius

    Flavelius

    Joined:
    Jul 8, 2012
    Posts:
    943
    Good points, GUI components and project search benefit from that distinction. Thanks.