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.
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.
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.
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.
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.
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.
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
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…
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
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.
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.
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?
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.
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.