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!
     
    levent_unity238 and JesOb like this.
  2. runevision

    runevision

    Joined:
    Nov 28, 2007
    Posts:
    1,892
    That's not supported.
     
    Gamba04 likes this.
  3. JesOb

    JesOb

    Joined:
    Sep 3, 2012
    Posts:
    1,109
    But Why?
     
    levent_unity238 likes this.
  4. runevision

    runevision

    Joined:
    Nov 28, 2007
    Posts:
    1,892
    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. JesOb

    JesOb

    Joined:
    Sep 3, 2012
    Posts:
    1,109
    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

    Joined:
    Nov 28, 2007
    Posts:
    1,892
    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:
    6,336
    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

    Joined:
    Nov 28, 2007
    Posts:
    1,892
    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:
    6,336
    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

    Joined:
    Nov 28, 2007
    Posts:
    1,892
    Yeah we've filed a case for it.
     
    JesOb and Baste like this.
  11. Deleted User

    Deleted User

    Guest

    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 by a moderator: Jun 29, 2019
  12. Deleted User

    Deleted User

    Guest

    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. Deleted User

    Deleted User

    Guest

    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.
     
  15. GiantLightStudios

    GiantLightStudios

    Joined:
    Jul 24, 2019
    Posts:
    9
    Any chance this has been changed in the 2 years since this thread was created? Or has anyone come up with a workflow to minimize the impacts of this issue?
     
  16. Patoto64

    Patoto64

    Joined:
    Jan 11, 2020
    Posts:
    3
    I also need this feature, it's very annoying and bug-prone having to re-assign references in an inherited script component. Placing my vote here for the prioritization of this feature.
     
    eskivor and JesOb like this.
  17. jlnorris

    jlnorris

    Joined:
    May 17, 2022
    Posts:
    7
    I've been looking into this as I want to be able to do it too, but I can see it could be very complicated to implement.

    What I'm going to do instead is, add a 2nd class in the prefab variant which has a reference to the inherited class from the prefab.

    E.g.
    prefab A has script X (which contains all the generic data for all objects of this type - in my case the weapon damages, fire delays, etc)
    prefab variant B inherits script X, and additionally has script Y (which contains specific behavior required for this variant - in my case the player's upgrade system which enemies do not use) which has a reference to script X and can pass along instructions to X as needed

    It obviously may take a few more methods to communicate between X and Y, but unless Y needs to see all of X it shouldn't be too onerous to add these.