Nested Prefab Composition vs Inheritance

I don’t have a lot of experience with nested prefabs. I understand how they work but haven’t tried designing a lot of them.

What are the things to look out for when deciding how to up nested prefabs/prefab variants? I kinda expect the “favor composition instead of inheritance” principle to come into play but it doesn’t seem completely the same as when you’re just dealing with code.

Some basic things make sense to me:

  • If your game had a dangling crane that holds an item (like a fruit, for points), you’d make a prefab for the crane, and a prefab for the fruit.
  • If your game had a regular goblin, and a strong goblin, it makes sense for the strong goblin to be a variant of the regular one, maybe with different values in its serialized fields. If they had extra moves, it wouldn’t be huge a problem. You could think of the regular goblin as the strong goblin, but with some moves disabled.

But I worry about the setups that say “a player and an enemy inherit from this thing” 'cause the player could very well have all sorts of abilities and movement rules that don’t apply to enemies and vice versa, even if they have similarities. Surely, some enemies could fly or pass through walls or go underground or even split into several GameObjects/Transforms.

It could be fine especially if you know what they’re going to be and consequently, what they’re never going to be. But if you’re at the start of development for a game that’s not solidified, wouldn’t deciding this inheritance too early make adjustments unnecessarily difficult?

As someone who tends to set up their important GameObjects into nested hierarchies anyway, I think it makes sense to using the “nesting” aspect for composition. eg, I’d put my collider and the “damage receiving” script on a child Transform instead of on the root Transform. If I make this attackable GameObject child a prefab, I can add that to any prefab that needs to be attackable regardless of what it is.

Does this way of proceeding have serious problems or is it what’s generally recommended?

Nested prefabs is essentially composition. If I understand you right, the way you’re looking at doing it is pretty much the way you should be doing it.

In Unity games development, Inheritance (especially when you’re newish) often gives you more problems than it tends to solve.

1 Like

The challenge to both approaches is planning and designing before committing. Both nested prefabs and prefab variants are relatively new concepts within Unity. Prior to Unity 2018, you could use neither paradigm, building each prefab from the ground up, or manually copying and modifying an existing prefab. The idea of making a change in one prefab that cascaded to descendants or prefabs that depended on that prefab was novel. Both ideas can solve problems and create more problems if not careful.

Prefab Variants

  • Inheritance based solution.
  • Allows you to create a base “prefab” and make variations, with each variant having it’s own flavor. Best suited for things that all prefabs in this family must have to succeed.
  • Changes to the master cascade to all variant unless the variant has already overriden a value.
  • Changes to a variant can be applied back to a master. (This is the most dangerous part of a prefab variant, as it’s easy to apply back a change to the master, which then cascades from the master down to other variants.

Nested Prefabs

  • Composition based solution
  • Allows you to easily add “building blocks” to any prefab.
  • Closest to how we assemble GameObjects in Unity, where we add components as needed.
  • Changes to nested prefab can be applied back to the original. Like prefab variants, this can lead to unwanted side effects.
  • Communication between nested prefabs can be more complicated than communication between common elements on a prefab variant.

To use your health component example, variants and nested prefabs are well suited for this. For a variant, your master “Character” class has the Health component, so by definition, a Player or Enemy prefab will also have the Health Component. It’s a great way to ensure that it’s not forgotten. For a nested prefab, it’s just a matter of dropping a Health prefab into each character, but that also means it’s easily forgotten. Communication can be trickier, because rather than GetComponent, we need to GetComponentInChildren or GetComponentInParent (or a combination of both… supposing that in our example Fighter is also a Nested Prefab, if the Fighter needs to check the owning character’s Health component, it would need to use transform.parent.GetComponentInChildren.

In the end, it’s what you’re most comfortable with. I’m not going to say that either solution is right or wrong. In fact, which solution is best could vary from project to project. We’re using a bit of both in the RPG series, in part to demonstrate the power of both. We’re leveraging the power of prefab variants for common components like the Health, Fighter, Mover, ActionScheduler, etc, and we’re leveraging the power of nested prefabs with components like DamageTextSpawner.

1 Like

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.

Privacy & Terms