Search Unity

How to make existing prefabs variants of a newly created base prefab?

Discussion in 'Prefabs' started by Xarbrough, Nov 7, 2018.

  1. Xarbrough

    Xarbrough

    Joined:
    Dec 11, 2014
    Posts:
    1,188
    I'm trying out the new workflow and like it very much when starting with a clean slate. However, now I'm trying to migrate existing content and couldn't figure out how to do this: I have several regular simple prefabs which I would like to turn into variants of a new base prefab. Is this possible and if, how? The manual only describes how to create a variant from an existing base, but not how to connect existing prefabs. Thank you!
     
    SLGSimon likes this.
  2. runevision

    runevision

    Joined:
    Nov 28, 2007
    Posts:
    1,892
    This is not possible, unfortunately. The way the Prefab system works, it's not possible to do this without changing IDs of objects in the Prefab, which would in turn mean that any references to it would break.

    The only way would be rather manual: To open the base Prefab and the intended derived Prefab and copy over GameObjects and components from the intended derived Prefab onto the base Prefab, then save the result as a new Prefab (choosing to make it a Prefab Variant when asked). And then replace the existing Prefab with this new one. This will break references to the Prefab as described, since you're essentially replacing the Prefab with a new one, but if that's acceptable it might be a way to go, and could possibly be automated with a little scripting.
     
    Xarbrough likes this.
  3. Deleted User

    Deleted User

    Guest

    Any chance this became possible in the last year (2019.3)? Dragging a prefab to another prefab or variant should convert it. Imagine if C# didn't let you change the base class after a class is created...
     
  4. Xarbrough

    Xarbrough

    Joined:
    Dec 11, 2014
    Posts:
    1,188
    I keep coming back to this problem ever since. Even in new projects. It's simply not possible to think ahead like this and plan all content top-down, from base to more derived or variant versions. Like in programming, I start with a simple prefab, but then after months of development I realize that I need two very similar prefabs. But the new prefab cannot be a variant of the existing one, instead, the old one should become a variant of the not-yet existing new prefab or both should be derived from a common base prefab.

    Edit: Ok, so it does work, (edit: for a single prefab) but not many people seem to know about it:


    To turn an existing prefab into a variant of a newly create base prefab do the following steps:
    1. Open existing prefab "Cat".
    2. Rename the GameObject root in prefab mode to "Animal".
    3. Drag the root object "Animal" into the project window.
    4. A dialog comes up, confirm that you want to create a new base and turn the open prefab into a variant of the newly created one.
    5. Rename root gameobject "Animal" back to "Cat" in the open prefab.
    6. Save
    You now have a base prefab "Animal" and a variant of it called "Cat" in the project.
     
    Last edited: Dec 4, 2019
  5. runevision

    runevision

    Joined:
    Nov 28, 2007
    Posts:
    1,892
    Yes, that does work. However, in your original post you said you wanted to make multiple Prefabs into variants of the same base Prefab (at least that's how I interpreted it) and you can't do that with the approach described in the video and which you outlined above, since every time you follow the steps you get a new base Prefab.
     
  6. Xarbrough

    Xarbrough

    Joined:
    Dec 11, 2014
    Posts:
    1,188
    Ah that's true! Also, it only works in a very simple example as shown in the video, but I've now tried it in our actual project and quickly realized that I need a different solution. When creating a base from an existing prefab, the base will have all child GameObjects and components and I couldn't find a way to remove some of them in the base but keep them as added overrides in the child.

    So afterall, I decided to use more nested prefabs instead of variants. So, basically, instead of trying to create a base-variant relationship with overrides, I now have two entirely separate prefab root objects, which then both have a series of nested prefab childs, which some of them they can share and some of them they override. Maybe one could say "composition over inheritance". :)
     
  7. runevision

    runevision

    Joined:
    Nov 28, 2007
    Posts:
    1,892
    Great if that works for you. It's virtually the same thing as well - the only difference is the root GameObject (if your nested Prefab is an immediate child). For all other GameObject's there's no difference between being part of a base Prefab or being part of a nested Prefab. The "composition versus inheritance" way of looking at it is not 100% representative since you can also make overrides on nested Prefabs (inside the outer Prefab) just like you can on a base Prefab inside a Variant.
     
    Xarbrough likes this.
  8. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,338
    I recently did something like this. We had our main character prefab, but wanted a simplified version that just shared the model, the animation stuff, and a simple script.

    I did this:
    - Created a copy (PrefabCopy) of the original prefab (OriginalPrefab)
    - Turned the root of OriginalPrefab into a base prefab (BasePrefab) by dragging the root into the hierarchy.
    - Opened BasePrefab, and deleted everything that was not supposed to be shared
    - Copied everything that had been deleted from PrefabCopy to OriginalPrefab.

    It wasn't that much work, but it got annoying, and it's a bit error-prone. This also only worker because the player prefab is spawned, and there's no references to it.

    If we could insert an empty prefab as a new base prefab, that would be a very acceptable workaround - then we could simply apply all the "modifications" we wanted the new base to have. I imagine that this could be done without breaking the ID's? You've written something about how IDs for prefabs work before, but I can't quite remember what it is - is it some kind of flag system?
     
  9. runevision

    runevision

    Joined:
    Nov 28, 2007
    Posts:
    1,892
    If the base is a new Prefab, then yes this should be compatible with the way we use the IDs. However, it wouldn't work to select an existing Prefab as the base (whether it's just an empty GameObject or not) as far as I understand. And so it still wouldn't be a way to refactor multiple existing Prefabs to share a common base.
     
    Baste likes this.
  10. olejuer

    olejuer

    Joined:
    Dec 1, 2014
    Posts:
    211
    Would it maybe be possible to select multiple existing prefabs and make them all variants of one, newly created, empty prefab?
    I think that would be a feature with which most of these work flows could be realized. Maybe we could even hack this ourselves somehow?
     
  11. runevision

    runevision

    Joined:
    Nov 28, 2007
    Posts:
    1,892
    No*

    The issue is that there is a deterministic relationship between the IDs of objects in a Prefab Asset, and the IDs of objects in the instance of that Prefab, such as inside a Prefab Variant. So we can compute the IDs in a new Variant based on the IDs in the base, or "reverse compute" the IDs in a new base based on the IDs in the Prefab that's being made into a Variant. But this doesn't work for making multiple different objects share the same new base. Trying to "reverse compute" the IDs based on one of the Prefabs will give different IDs than if we "reverse compute" them based another of the Prefabs.

    * When I say it's not possible in this thread, I mean in a clean way that preserves object references. It should be possible if we change the IDs of the objects in the Prefabs that are meant to get a new common base, but that means that any references you have to those objects will become missing. Also, I'm not 100% all the details in my explanation here are entirely correct, but the basic gist of it should be.
     
    IgorAherneBusiness and olejuer like this.
  12. Qhuhuit

    Qhuhuit

    Joined:
    Feb 17, 2018
    Posts:
    39
    So true, Same need today and it's been several times I ended up to this thread.
    Unity should make something about this !
     
    asadmuzammil77 likes this.
  13. starikcetin

    starikcetin

    Joined:
    Dec 7, 2017
    Posts:
    340
    Any progress on this? The need for a feature like this comes up a lot. Simply diffing the prefabs against each other and proceeding to remove the same parts on the soon-to-be-variant should do the trick, no?
     
  14. aazzolini

    aazzolini

    Joined:
    Sep 7, 2019
    Posts:
    8
    I'm running into the same issue / feature request.

    Question, would it be possible to create a script to automatize this?
     
  15. Alturis2

    Alturis2

    Joined:
    Dec 4, 2013
    Posts:
    38
    +1. Seems like this should definitely be possible.
     
  16. koirat

    koirat

    Joined:
    Jul 7, 2012
    Posts:
    2,073
    Rumors says runevision changed job because of this issue ;)
     
  17. kalineh

    kalineh

    Joined:
    Dec 23, 2015
    Posts:
    241
    This would be very useful, we have many cases where a few objects have been independent prefabs and would like to have a base prefab. We avoid making new objects and copying things because we always end up with enormous errors when making new objects with the same name as previous existing objects. Cursed asset management
     
    SLGSimon likes this.
  18. goldbug

    goldbug

    Joined:
    Oct 12, 2011
    Posts:
    768
    in git, you can see that Unity 2022.2 will have the function:
    PrefabUtility.ReplacePrefabAssetOfPrefabInstances
    with several overloads

    I wonder if this function could be used for this use case.
    I also would really appreciate this feature. I am having to redo a bunch of rather complicated prefabs because of this.
     
    Qhuhuit likes this.
  19. goldbug

    goldbug

    Joined:
    Oct 12, 2011
    Posts:
    768
    This is working for me in unity 2022.2.

    To reparent a prefab:
    1. double click on the prefab to open it in the hierarchy view.
    2. right click on the root object of the prefab and click on Prefab -> Reconnect Prefab
    3. then select the prefab you want as a parent
    4. When asked, click on "use old name"
    5. Then click on the overrides dropdown and adjust as necessary.

    I still have to do one at a time, I have a few hundred prefabs, so it is time-consuming, but this is so much better than having to rebuild them.
     
    Last edited: Dec 13, 2022
    olejuer likes this.
  20. Mads-Nyholm

    Mads-Nyholm

    Unity Technologies

    Joined:
    Aug 19, 2013
    Posts:
    219
    We have had to disable the ability to Convert the plain root GameObject for a Prefab to a Prefab instance as you are doing above as this was breaking all instances of the prefab in the Scene and other Prefabs: All instances was loosing their default overrides and references to its objects would break. We had already prevented doing this for Variant assets as it was also breaking, but we missed these safety check for plain GameObjects in Prefab Mode as well.
    The change will land in Unity 2022.2.2f1.

    We don't currently have a way to refactor Prefabs Variant inheritance due to the way we calculate fileIDs. Changing this would be a breaking change.
     
  21. goldbug

    goldbug

    Joined:
    Oct 12, 2011
    Posts:
    768
    Thanks for the information @Mads-Nyholm . That would have caught me by surprise. I'll convert all my prefabs before I upgrade.

    I learned the hard way the references to the converted prefabs were broken. It is a price I am willing to pay, but I understand it may be too disruptive to others.

    Is this something that you guys can solve? Maybe go through all other prefabs and scenes and fix the references?
     
  22. Qhuhuit

    Qhuhuit

    Joined:
    Feb 17, 2018
    Posts:
    39
    @Mads-Nyholm is this feature considered by Unity or in research ?
    In the early stage of a project, there is no way to know in advance that some prefabs will share a same base in the future, unless doing extensive planning and sticking to the plan, which is too unrealistic.
    I've come across this issue several times in most of my projects for years, could really help to have a solution.
    For now, everything has to be done manually, deleting the existing prefabs, loosing all references, making a new root prefab by hand, creating the variants, replacing the old references with the new variants...

    Even if the instances loose their references, @goldbug solution is still the only way there is to not rebuild everything, so I don't really get your argument...
     
  23. Mads-Nyholm

    Mads-Nyholm

    Unity Technologies

    Joined:
    Aug 19, 2013
    Posts:
    219
    We have researched various attempts but none have had a perfect solution where all references can survive after a Variant inheritance refactor. We are very well aware of the pain it is causing. The problem is that all serialized references in other files will break due to the way fileIDs are generated for Prefab objects that have nested instances. And changing the fileID generation would be a breaking change so we have ruled that out so far.
    Currently we are looking at a solution that will allow this refactor but with the consequence that only the root Transform keeps its fileID and therefore default overrides and references to this root instance Transform will survive the inheritance refactor. We would need to show a dialog with a warning in the Editor and note in the documentation what the consequences would be using this inheritance refactoring functionality. And some references would need to be rewired up again in scenes and other prefabs.
     
    nytcj likes this.
  24. Katerlad

    Katerlad

    Joined:
    Mar 26, 2015
    Posts:
    19
    @Mads-Nyholm - how about a built in way of using composition of many prefabs, but not by nested prefabs.

    Imagine a new unity built in component that lets you choose multiple prefabs that you want their components and values of those prefabs to be attached to this new prefab. And any changes made to attached prefabs will reflect on the new prefab unless over ridden. This can be accomplished with many different nested prefabs, but why not add this functionality for just the root or parent.
     
    Marc-Ducret and Totoro83y like this.
  25. jyfc

    jyfc

    Joined:
    Feb 19, 2016
    Posts:
    9
    Is this the best place to look out for updates or is there a thread / feature tracker page somewhere else? I think it's safe to say this would be a huge workflow improvement for everyone, so we're keen to stay updated on progress here.