Search Unity

Prefab Variant With Derived Class

Discussion in 'Prefabs' started by lorenzofman2, Apr 15, 2019.

  1. lorenzofman2

    lorenzofman2

    Joined:
    Nov 8, 2014
    Posts:
    1
    Hey people!

    Unity nested prefabs are great. No doubt about it.
    Recently I got into a problem where it make a lot of sense to have a prefab, let's name it A and a prefab variant that is B.
    Using Unity nested prefabs it's really easy to do it.
    My prefab A would have a component ClassA.
    My problem was that I wanted B prefab to have a class ClassB that inherits from ClassA.
    ClassB : ClassA

    How can I achieve that?
    Does Unity support this now?

    I couldn't find nothing on the web.

    Just to be clear. I know I can just remove ClassA from prefab B and add ClassB to it, but what I want is ClassA attributes to be reflected in prefab B.

    Thanks!
     
    Jes28 likes this.
  2. runevision

    runevision

    Unity Technologies

    Joined:
    Nov 28, 2007
    Posts:
    1,615
    That's not supported.
     
  3. Jes28

    Jes28

    Joined:
    Sep 3, 2012
    Posts:
    381
    But Why?
     
  4. runevision

    runevision

    Unity Technologies

    Joined:
    Nov 28, 2007
    Posts:
    1,615
    As with most things that are not supported: Because nobody implemented it.

    It's a complex feature request that needs an interaction between Prefab variants (a form of inheritance) and the completely different system of script class inheritance. It would require a lot of work and a lot of other feature requests have been much more widely requested, so it's not near the top of priorities of things for us to address.
     
  5. Jes28

    Jes28

    Joined:
    Sep 3, 2012
    Posts:
    381
    What about just allowing simple override on m_Script property so we can just replace it with another script like this work earlier?
     
  6. runevision

    runevision

    Unity Technologies

    Joined:
    Nov 28, 2007
    Posts:
    1,615
    Changing a script to another type would in previous versions break the Prefab connection. Since we don't support breaking Prefab connections anymore, this is no longer an option. But even before you would not get updates from the Prefab Asset due to the broken connection. So it has never really worked.
     
  7. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    4,224
    Is there a reason why m_Script can't be overridden like any other property? The serializer seems to handle switching the script pretty gracefully, replacing fields by their name automatically. So it seems like changing the script causing a disconnect is an added guard rather than something that's a given. Or does dragging a new script in (with the inspector in debug mode) cause a script remove + a script add?

    I guess the hard part is where to store values of fields that are only on the other class? And what to do with fields that are not on the other class?

    Also, attempting to swap the attached script on a variant in prefab mode seems to work - it does all of the correct things. The console just complains that "Disconnecting is no longer implemented", and the change is lost when leaving prefab mode.
     
  8. runevision

    runevision

    Unity Technologies

    Joined:
    Nov 28, 2007
    Posts:
    1,615
    It's not an added guard. We have code that handles Prefab overrides and patches up the values with those overrides. Anything that handles values/properties will have to specifically have code for this in order for the overrides to have an effect. According to Steen, the code that determines which type of script component to construct based on the serialization of that component is not currently aware of overrides. Special handling would have to be implemented for this to work. It's not impossible, but doesn't come for free either, hence why I said it's competing with all other feature requests in our prioritization.

    This shouldn't be a problem I think. It's all name based.

    Right, because Prefab importing isn't aware of overrides in the code that determines what type of component to construct.
     
    Baste likes this.
  9. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    4,224
    Could the error behaviour be made better? I assumed this worked out of the box the first time around, because I didn't have the console open, and the inspector behaved as normal.

    The "Disconnecting is no longer implemented" message should probably be "Replacing a script on a prefab variant or child is not supported", and the script should not show up as changed.
     
  10. runevision

    runevision

    Unity Technologies

    Joined:
    Nov 28, 2007
    Posts:
    1,615
    Yeah we've filed a case for it.
     
    Jes28 and Baste like this.
  11. Alexees

    Alexees

    Joined:
    Nov 8, 2017
    Posts:
    189
    So this is about it, right:
    - Create Prefab variant tree as long as components are identical
    - Add fully matured scripts to their respective Prefab variant level
    - Don't use RequireComponentAttribute in your base classes as they do not go on base Prefabs and are therefore unnecessary

    The culprit seems to be that once you see a chance for prefabs to be superclassed, you're doomed :p

    It would be really nice if you could right-click on one or many gameobjects and select create base prefab. It could traverse all prefabs and find similarities in their structure. You could then choose what the default for the new base for each field is.
    I never know what a class turns out to be in the end and I always move code up if possible. It would be nice if that was possible with prefabs too.

    What actually really sucks is the fact that you cannot view multiple prefab modes at the same time. If you go down the road of recreating your prefabs based on a newly created base you need to copy component configurations over. This got a tedious open, copy, close, open, paste, close, open...
     
    Last edited: Jun 29, 2019
  12. Alexees

    Alexees

    Joined:
    Nov 8, 2017
    Posts:
    189
    One more: You have to think about order of your components, because you can't rearrange them beyond the prefab derivation chain. If you put something in the parent you want to execute last, you're doomed :p
     
  13. MorZPlaytika

    MorZPlaytika

    Joined:
    Feb 15, 2019
    Posts:
    5
    Well, that's what the script execution order and DefaultExecutionOrderAttribute are for :)

    And in regards to the topic at hand, we'd also really like to see this feature implemented at some point.
    Would be really useful in our case where variants are used for inheritance-like behaviours, yet the base settings and need to be separately bound for each variant that has a concrete implementation of a deriving script.
     
  14. Alexees

    Alexees

    Joined:
    Nov 8, 2017
    Posts:
    189
    Not in this case. Execution of components on GameObject is already defined by their order. Doing it the ExecutionOrder way with a lot of variants would result in a gigantic mess in the order list.