Search Unity

Replace nested prefab with its variant?

Discussion in 'Prefabs' started by Wojtek_Golowkow_iDreams, Jun 21, 2018.

  1. Wojtek_Golowkow_iDreams

    Wojtek_Golowkow_iDreams

    Joined:
    Nov 2, 2015
    Posts:
    1
    Hi there!
    I've got a feature request that seems to be quite simple with the current system.

    In the presentation video you are showing how you can scale an instance of a nested prefab to create smaller versions of a marker.
    What I would like to see is taking it one step further, so that I can create a variant of the marker prefab and replace the nested instance of marker with that variant. That way I can keep the small marker consistent across different parent prefabs.
     
    paradizIsCool, ChessMax and BAIZOR like this.
  2. BAIZOR

    BAIZOR

    Joined:
    Jul 4, 2013
    Posts:
    112
    Agree, it's a useful feature!
    +1
     
  3. cirocontinisio

    cirocontinisio

    Joined:
    Jun 20, 2016
    Posts:
    884
    If I understood it correctly, you should be able to do that by just dragging the instance of the marker Prefab into the Project Window, and ask to create a Variant out of it in the dialog that ensues. Was this that you were asking?
     
    runevision and rakkarage like this.
  4. rz_0lento

    rz_0lento

    Joined:
    Oct 8, 2013
    Posts:
    2,361
    I'd love to have option to swap prefab instances from the scene too but I don't really know how one would implement it intuitively, considering that drag & drop is traditionally putting things in the hierarchy...

    Imagine you have a variant, lets call it a dog but you realize that you wanted to have cat variant there instead, atm it's not possible to swap the prefab ref from scene hierarchy directly, instead you need to drag the other prefab there and copy the transform to another.
     
  5. cirocontinisio

    cirocontinisio

    Joined:
    Jun 20, 2016
    Posts:
    884
    I thought about this, and I agree we should have it. In my games, I used to use a simple Replacement script, which I can't find right now. This asset might provide that functionality too - but again - I agree we should implement it somehow. I am just wondering what that means when you're replacing a Prefab with one of its variants… can you, should you carry the Overrides over? And how to match them?
     
    paradizIsCool and jashan like this.
  6. StunAustralia

    StunAustralia

    Joined:
    Jul 1, 2018
    Posts:
    33
    I was working on something similar with the previous prefab system and according to my notes, I'd thought the following may be a workable UX to approach it:
    • After selecting the gameobject at whatever level - [Alt]-Mousewheel would find the closest parent prefab in the hierarchy and just destroy and re-instantiate through a circular list of all replacements. I'd imagine in the new workflow, that could automatically just be the base and all its variants

    • All overrides of the original/starting object to be applied where they could be with all overrides remembered while the object remained selected - once the object was no longer selected, the list of original overrides would be lost (but hey, that's what undo is for, right?)

    • The override would preserve any nested prefabs that differed from the original parent prefab as it would any other overrides. Restoring the original nested prefabs would be the same operation as clearing any other override.


    (Liking the new prefab workflow btw!)
     
  7. a_deadman

    a_deadman

    Joined:
    Jan 20, 2014
    Posts:
    5
    Has there been any progress on this ?
    I'm working on a drop-in Firebase Authentication GUI(https://github.com/purple-movies/FirebaseAuthUI) to allow you to implement/prototype games with user-accounts easily.

    I'm testing out the package with one of my game-projects and I'd like to make a prefab-variant from the auth-panel prefab I added to the package and then replace buttons and text-inputs within with skinned-variants styled for the game. If we could swap-out variants nested in another variant like you might with a sub-class of something that'd make it really easy to skin UI with prefab-variants.
     
  8. jashan

    jashan

    Joined:
    Mar 9, 2007
    Posts:
    3,307
    Probably a long time ago, Unity had a left mouse click modifier that would replace the game object that you drop a prefab on with the prefab. It was ALT or CMD (I was on Mac back then), or maybe SHIFT.

    The way this worked back then was that the transform of the original object was kept, also, as far as I remember, all references to that object were kept, if possible (this is the important thing here IMHO ;-) ), and everything else from the original object was overridden with the prefab. I'm not perfectly sure what happened when you override one prefab with another one, or if that was even supported ... this was probably before 2010.

    Anyways, what I sometimes would need rather desperately, and probably even more so with the new prefab system, is basically the opposite operation of "unpacking" a prefab. So it would be "packing a game object".

    The way I would expect this to work:
    • Most important: Any references to this game object that can be kept, should be kept. In other words, if the game object had a "MyAwesomeComponent"-component, and the prefab has that same component on the same hierarchy level, and external references to the old game object that refer to MyAwesomeComponent should still be intact. This would be such a time saver because the biggest issue with replacing a game object with a prefab (or replacing a prefab instance with another prefab) is that you may accidentally break references, which can cause really nasty bugs.
    • From that follows: All components and hierarchy that existed in the old game object, and still exist in the new one, should remain, with the overrides properly applied.
    • Any components or hierarchy that is missing (e.g. original game object had 3 children, prefab only has one) should probably disappear (and probably, to keep things sane, you'd only look at the first child of the original game object to see if that has components to be re-used by the prefab; so child order would matter)
    • Any values that are different in the new prefab, compared to the original game object (or old prefab instance), should become overrides ... it's easy enough to undo those in a second step if you want them consistent with the new prefab
    Obviously, one thing that would be really nice to have would be to keep anything that's not part of the prefab as overrides, including additional components and children. That would be the safe route for the primary use case of this whole procedure: Making something a prefab that wasn't a prefab before, or replacing one prefab with another one, without breaking the scene.

    Just to give two really simple scenarios where this feature can be a life-saver:
    1. You're in the middle of crunching out a prototype and are too lazy to create a prefab for this little building-block that you then copy 30 times, complete the level, continue building a game and realize that prototype will become the actual level and having a prefab for this building-block would really be preferable but with all the dependencies, it's a nightmare, so you write a few scripts to make changes to those building-blocks, which ends up being quicker than re-building everything properly with prefabs. With the "pack game object"-feature, you'd instead write a script that replaces all your building-blocks with the prefab you finally created from the first ;-)
    2. You have a prefab that your build your level with but after making some modifications, you realize that actually, those 30 prefab instances are not really all the same, but 4 different prefab variants. Again, dead end with the current system (rebuild it all), rather elegant solution with the feature outlined above (you create those four variants, then carefully replace all prefab instances that should be another variant, done, scene clean).
     
    Tymianek and Meceka like this.
  9. a_deadman

    a_deadman

    Joined:
    Jan 20, 2014
    Posts:
    5
    In the meantime I've decided to add something to the Firebase Auth UI sub-module with the whole Auth UI rebuilt from prefab-variants. These are all post-fixed with `DropIn` and are designed to be the prefabs used in an actual project with all the nested-prefabs variants that you'd want to skin(buttons, etc).

    This means the UI prefab in a project only inherits nested-prefabs from the base-prefab that don't change a lot, or they inherit changes by merging changes from up-stream on the repository. Any fixes to the auth-UI prefab-variant would have to be made on the master branch and then merged in to branches used by sub-modules for projects using the package.

    @jashan gave me an idea tho. If I unpack the prefabs down to the nested prefabs that'd want to be skinned and then rebuilt them - then it pretty much makes clones of all the prefabs used. Which I guess is what I did manually in the previous description. Not sure how hard it'd be to write an editor-extension to do this.
     
  10. a_deadman

    a_deadman

    Joined:
    Jan 20, 2014
    Posts:
    5
    Hi @cirocontinisio - is this on the roadmap, or is there any way we could build an editor extension that'd allow us to set a reference to a variant for a nested-prefab ?
     
  11. Deleted User

    Deleted User

    Guest

    Hooking into this. @cirocontinisio I would like to know if this is something you guys are working on as well.

    I would like to see this as keeping available values when replacing if possible. If the variant is a higher order (more changes and scripts), defaults get added, if there's less, less get added. If I WANTED to override, I could just place a copy next to the original, clone the transform and delete the old one. Could be tricky to keep references to it this way though.

    The most intuitive would be a right click menu for prefabs providing a "replace with variant" entry that lists hierarchical relevant prefabs. You could then further add entried for override all, keep all (the way I suggested further up) and override selectively, which would show a popup like the one in the inspector when reverting or applying changes.
     
    Last edited by a moderator: Apr 23, 2019
  12. antti_partagames

    antti_partagames

    Joined:
    Nov 5, 2015
    Posts:
    18
    I'm currrently working on a network game and at this moment am stuck with this problem.

    1) I need to create a GameObject for a player's connection.
    2) At that specific moment I don't know which player it is, before the player sends some kind of ID, so I need to instantiate the base prefab
    3) A millisecond later the player informs the server which connection it is. At that moment it would be useful to be able to start appending the variant stuff into the base prefab, to get the proper player visuals in place
    4) I *could* split the prefabs into modularized pieces to handle the visual stuff, but using variants would be so much more convenient, I think

    Not sure if this is even the optimal way to do things but this sounds like it could be useful.
     
  13. Deleted User

    Deleted User

    Guest

    @antti_partagames The player spawned does not necessarily need to BE the player played. It's probably possible to swap him out, but I wouldn't do that. Variants are not the way to do this, they're there for a fast way of creating "different" prefabs. If you need different stuff spawned depending on player information, spawn a player that essentially is a manager and afterwards spawn the actual player. Only because the player object is the only one with authority always on it's side doesn't mean the avatar or what ever couldn't be a different gameobject spawned afterwards.
    But in your case let the player spawn the visual in, maybe even locally on each instance.
     
    BrandStone likes this.